×
INTELLIGENT WORK FORUMS
FOR ENGINEERING PROFESSIONALS

Log In

Come Join Us!

Are you an
Engineering professional?
Join Eng-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Eng-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Report all links in assembly

Report all links in assembly

Report all links in assembly

(OP)
Hello,

I wanna process all parts in assembly to report all links and then search for parent. Now I have journal which was created to report all broken links. Below is some code:

CODE

Sub reportComponentChildren1( ByVal comp As Component, ByVal indent As Integer)

Dim workPart As Part = theSession.Parts.Work
Dim dispPart As Part = theSession.Parts.Display	
	
For Each child As Component In comp.GetChildren()

	Dim MyPart As Part = child.Prototype.OwningPart

	Try

		if child.IsSuppressed = true then

			Continue for
			
		end if
			
		Catch e11 As Exception
			
		theSession.ListingWindow.WriteLine("Failed: " & e11.ToString)

	end try

	If LoadComponent(child) Then
 
		Dim sourceTag As Tag
		Dim Parentname as string
		Dim linkBroken As Boolean = True

		For Each theFeature as Features.Feature In MyPart.Features
			
			If theFeature.FeatureType.Contains("LINKED") Then
				
				theUfSession.Wave.IsLinkBroken(theFeature.Tag, linkBroken)
		
				If linkBroken Then
					
					theUfSession.Wave.AskbrokenLinkSourcepart(theFeature.Tag, Parentname, sourceTag)
		
				end if			

			else			
				
				theUfSession.Wave.AskLinkSource(theFeature.Tag, true, sourceTag)

				If sourceTag = Tag.Null Then

					lw.WriteLine("could not fully load parent file...")

				Else 

   				End if
			End if
		Next
	End if
Next
End sub 

I receive an error:

CODE

Failed: NXOpen.NXException: The first parameter passed in was invalid.
   w NXOpen.UF.UFWave.AskLinkSource(Tag linked_feature, Boolean allow_load, Tag& source_entity)
   w NXJournal.reportComponentChildren1(Component comp, Int32 indent) in C:\Users\...\AppData\Local\Temp\NXJournals41836\journal0.vb:linee 218
   w NXJournal.Main() in C:\Users\...\AppData\Local\Temp\NXJournals41836\journal0.vb:line 75 

Line 75:
ReportComponentChildren1(c.RootComponent, 0)

Line 218:
theUfSession.Wave.AskLinkSource(theFeature.Tag, true, sourceTag)



With best regards
Michael

RE: Report all links in assembly

The program has the following logic (simplified pseudocode):

CODE

IF linked feature THEN
    link broken? - get broken source
ELSE
    ask link source
END 

Which basically says to check the link source on a feature that is NOT linked.

Also note that not all linked features will contain the word "LINKED" in the feature type. The following code from GTAC shows a more robust method to identify linked features.

http://solutions.industrysoftware.automation.sieme...

www.nxjournaling.com

RE: Report all links in assembly

(OP)
Thanks @Cowski now I see it. I used "else" in wrong place. I know that not all features has "Linked", but in my work I only use linked body and sometimes Linked mirror. For this two link I wanna find parent, and then check if it isn't from the different order. I will check the link You provided.

With best regards
Michael

RE: Report all links in assembly

(OP)
Hello,
I finally finished my journal. I used some part of code from NXjournaling. Below is the code, maybe it will be useful for someone.

CODE

Option Strict Off

Imports System
Imports System.Collections.Generic
Imports NXOpen
Imports NXOpen.UF
Imports NXOpen.Assemblies

Public class PList1

	Public Property Part_Name As String
	Public Property Link_Name As String
	Public Property Parent_Name As String
	Public Property Link_Status As String

Public Sub New(ByVal PartN As String, ByVal ParentN As String, ByVal LinkN As String, ByVal LinkS As String)
'Public Sub New(ByVal PartN As String, ByVal LinkN As String, ByVal ParentN As String, ByVal LinkS As String)
'Public Sub New(ByVal PartN As String, ByVal ParentN As String)

	Part_Name = PartN
	Link_Name = LinkN
	Parent_Name = ParentN
	Link_Status = LinkS

End Sub

End Class

 
Module wave_links_part_only
 
	Dim theSession As Session = Session.GetSession()
	Dim theUfSession As UFSession = UFSession.GetUFSession
		
 	Dim workPart As Part = theSession.Parts.Work
	Dim dispPart As Part = theSession.Parts.Display
	
	Dim PartList1 as New list (of PList1) ()
	Dim List1 as New List (of String) 
	'Dim Lista2 as New List (of String) 		
	Dim List3 as New List (of String) 
	Dim List4 as New List (of String) 
	Dim List5 as New List (of String) 
	Dim List6 as New List (of String)
	
	Dim lw As ListingWindow = theSession.ListingWindow
 
Sub Main()
 
	If IsNothing(theSession.Parts.Work) Then
		
		'active part required
		Return
			
	End If
 
	'Dim workPart As Part = theSession.Parts.Work
	
	lw.Open()
	
	Dim searched_string as string
	
	searched_string = Inputbox("Please enter searched string. Minimum 3 chars.", "Enter searched string.", " ")
       
	If searched_string = " " Then
	
		MsgBox("You have to enter searched string.", vbOKOnly, "Error")
		Exit Sub
		
	ElseIf searched_string = "" Then
	
		Exit Sub
		
	End If
	
	If Len(searched_string) < 3 Then
	
		Msgbox("You have to enter minimum 3 chars to continue.", vbOKOnly, "Error")
		Exit sub
		
	End If 
	
	
 	Try
	
		Dim c As ComponentAssembly = dispPart.ComponentAssembly

		if not IsNothing(c.RootComponent) then

			ReportComponentChildren(c.RootComponent, 0)
			ReportComponentChildren1(c.RootComponent, 0)

		else

			lw.WriteLine("Part has no components")

		end if

		Catch e As Exception

		theSession.ListingWindow.WriteLine("Failed: " & e.ToString)

	End Try
	
	
	if Not IsNothing(Partlist1) AndAlso Partlist1.Count > 0 Then
		
		'Partlist1.sort(Function(x, y) x.part_name.CompareTo(y.Part_name))
		partlist1.sort(AddressOf Comparer)	
	
		lw.writeline(" ")
		lw.writeline("*************************************************************")
		lw.writeline("*               Parts with searched links:                  *")
		lw.writeline("*************************************************************")
		'lw.writeline(" ")
		lw.writeline("-------------------------------------------------------------")
		lw.writeline("|  Part name  |  Parent name  |  Link name  |  Link Status  |")
		lw.writeline("-------------------------------------------------------------")
		lw.writeline(" ")

		Dim Prt1 as String = nothing
		Dim Prt2 as String = Nothing
		
		for each Part_ as PList1 in Partlist1
			
			if Part_.Parent_Name.Contains(searched_string) then 
				
				Prt1 = Part_.Part_Name
					
				If Prt2 = nothing then 
							
					lw.writeline(Part_.Part_Name & " | " & Part_.Parent_Name & " | " & Part_.Link_Name & " | " & Part_.Link_Status)
					
				elseif Prt2 <> Prt1		
				
					lw.writeline(" ")
					lw.writeline(Part_.Part_Name & " | " & Part_.Parent_Name & " | " & Part_.Link_Name & " | " & Part_.Link_Status)
				else 

					lw.writeline(Part_.Part_Name & " | " & Part_.Parent_Name & " | " & Part_.Link_Name & " | " & Part_.Link_Status)
					
				end if 	
					
				Prt2 = Prt1
	
			end if
		next		
		
	end if

	lw.Close()
 
End Sub

'*****************************************************************************************
' Empty run
'*****************************************************************************************
Sub reportComponentChildren( ByVal comp As Component, ByVal indent As Integer)

	Dim workPart As Part = theSession.Parts.Work
	Dim dispPart As Part = theSession.Parts.Display

	For Each child As Component In comp.GetChildren()
	
		Dim MyPart As Part = child.Prototype.OwningPart

		Try

			if child.IsSuppressed = true then

				'lw.writeline("   Error: " & child.DisplayName & ".prt" & " -> " & "Part is closed")
				list4.add(child.name)
				Continue for
				
			end if
		
			Catch e1 As Exception
			
				theSession.ListingWindow.WriteLine("Failed: " & e1.ToString)

		end try

		If LoadComponent(child) Then
				
		Else

			'component could not be loaded

		End If

		reportComponentChildren(child, indent+1)
	   
	Next
	
End Sub

'**********************************************************
' Looking for Links
'**********************************************************
Sub reportComponentChildren1( ByVal comp As Component, ByVal indent As Integer)

	Dim workPart As Part = theSession.Parts.Work
	Dim dispPart As Part = theSession.Parts.Display	
	
	For Each child As Component In comp.GetChildren()

		Dim MyPart As Part = child.Prototype.OwningPart

		Try

			if child.IsSuppressed = true then

				Continue for
			
			end if
			
			Catch e11 As Exception
			
				theSession.ListingWindow.WriteLine("Failed: " & e11.ToString)

		end try

		If LoadComponent(child) Then

			Const undoMarkName As String = "report wave links"
			Dim markId1 As Session.UndoMarkId
			markId1 = theSession.SetUndoMark(Session.MarkVisibility.Visible, undoMarkName)
	 
	 		if not list3.contains(MyPart.leaf) then 
							
				list3.add(MyPart.leaf)
			
				Dim theWaveLinks As New WaveLinkReport(mypart)
				ReportWaveLinks(theWaveLinks, False, mypart)			
								
			End if
			 
		Else

			'component could not be loaded

		End If 		

		reportComponentChildren1(child, indent + 1)

	Next

End Sub


Sub ReportWaveLinks(ByVal someLinkReport As WaveLinkReport, ByVal suppressNull As Boolean, ByVal mypart As Part)
 
	If suppressNull And someLinkReport.WaveFeatures.Count = 0 Then
	
		Return

	End If
	
  
	If someLinkReport.WaveFeatures.Count = 0 Then

		Return
			
	End If
	
 		
	lw.WriteLine("")
	lw.WriteLine(mypart.leaf & ":")
	lw.WriteLine("")
	
	Dim status as String
	
	For Each temp As WaveFeature In someLinkReport.WaveFeatures
		
		For Each parent As String In temp.WaveParents
							
			If temp.IsBroken Then
				
				lw.WriteLine("    " & parent & "  ->  " & temp.Feature.GetFeatureName & " -> Link is broken! ")
				status = "Broken"						
				
			Else 

				lw.WriteLine("    " & parent & "  ->  " & temp.Feature.GetFeatureName)
				Status = "Alive"
				
			End If
			
			Partlist1.add(new PList1(MyPart.name, Parent, temp.Feature.GetFeatureName, status))
					
		Next		
	
	'lw.WriteLine("")
		
	Next
 
	lw.WriteLine("")
 
End Sub

'**********************************************************
' Function loading components
'**********************************************************
Private Function LoadComponent(ByVal theComponent As Component) As Boolean
 
	Dim thePart As Part = theComponent.Prototype.OwningPart
	Dim partName As String = ""
	Dim refsetName As String = ""
	Dim instanceName As String = ""
	Dim origin(2) As Double
	Dim csysMatrix(8) As Double
	Dim transform(3, 3) As Double
 
	Try
		
		If thePart.IsFullyLoaded Then
		
			'component is fully loaded
				
		Else
			
			'component is partially loaded
				
		End If
			
		Return True
			
		Catch ex As NullReferenceException
		
			'component is not loaded
			
			Try
			
				theUfSession.Assem.AskComponentData(theComponent.Tag, partName, refsetName, instanceName, origin, csysMatrix, transform)
 
				Dim theLoadStatus As PartLoadStatus
				theSession.Parts.Open(partName, theLoadStatus)
 
				If theLoadStatus.NumberUnloadedParts > 0 Then
	
					Dim allReadOnly As Boolean = True
					
					For i As Integer = 0 To theLoadStatus.NumberUnloadedParts - 1
					
						If theLoadStatus.GetStatus(i) = 641058 Then
						
							'read-only warning, file loaded ok
							
						Else
						
							if not list5.contains(partname) then 
							
								'641044: file not found
								lw.WriteLine("File not found: -> " & partName)
								list5.add(partName)
								allReadOnly = False
							
							else
							
								'lw.WriteLine("	File not found: -> " & partName)
								allReadOnly = False
								
							end if
							
						End If

					Next

					If allReadOnly Then
					
						Return True
						
					Else
					
						'warnings other than read-only...
						Return False
						
					End If
					
				Else
				
					Return True
					
				End If
 
				Catch ex2 As NXException
				
					if ex2.message = "File not found" then 
				
						if not list6.contains(partname) then 
				
							lw.WriteLine("Error: File not found" & " -> " & partname)
							list6.add(partName)
						
						else
				
							'lw.WriteLine("	Error: " & partname & " -> " & "File not found")	
					
						end if	
		
					else
				
						lw.WriteLine("Error: " & partname & " -> " & ex2.Message)
					
					end if
				
					Return False
					
			End Try
			
			Catch ex As NXException
		
				'unexpected error
				lw.WriteLine("error: " & ex.Message)
				Return False
					
	End Try
 
End Function

'**********************************************************
' Compare component function
'**********************************************************
Private Function Comparer(ByVal x As Plist1, ByVal y As Plist1) As Integer

	Dim result As Integer = x.Part_name.CompareTo(y.Part_name)

	If result = 0 Then

		'result = x.Link_name.CompareTo(y.Link_name)
		result = x.Parent_Name.CompareTo(y.Parent_name)
		
		If result = 0 Then

			result = x.Link_name.CompareTo(y.Link_name)
			'result = x.Parent_Name.CompareTo(y.Parent_name)
		
		end if
			
	End If
	
	Return result

End Function


Public Function GetUnloadOption(ByVal dummy As String) As Integer
 
	'Unloads the image immediately after execution within NX
	GetUnloadOption = NXOpen.Session.LibraryUnloadOption.Immediately
 
End Function
 
End Module



Public Class WaveLinkReport
 
	Private cSession As Session = Session.GetSession
	Private cUfSession As UFSession = UFSession.GetUFSession
 
 
	Private cPart As Part
	Public Property Part() As Part
		Get
			Return cPart
		End Get
		Set(ByVal value As Part)
			cPart = value
			Me.ExamineFeatures()
			Me.FindUniqueParents()
		End Set
	End Property
 
	Private cWaveFeatures As New List(Of WaveFeature)
	Public ReadOnly Property WaveFeatures() As List(Of WaveFeature)
		Get
			Return cWaveFeatures
		End Get
	End Property
 
	Private cUniqueWaveParents As New List(Of String)
	Public ReadOnly Property UniqueWaveParents() As List(Of String)
		Get
			Return cUniqueWaveParents
		End Get
	End Property
 
	Public ReadOnly Property NumberOfBrokenLinks() As Integer
		Get
			Return cBrokenLinks.Count
		End Get
	End Property
 
	Private cBrokenLinks As New List(Of WaveFeature)
	Public ReadOnly Property BrokenLinks() As List(Of WaveFeature)
		Get
			Return cBrokenLinks
		End Get
	End Property
 

	Public Sub New(ByVal thePart As Part)
 
		Me.Part = thePart
 
	End Sub
 

	Private Sub ExamineFeatures()
 
		For Each tempFeature As Features.Feature In cPart.Features
 
			If IsWaveFeature(tempFeature) Then
 
				Dim newWaveFeature As New WaveFeature(tempFeature)
				cWaveFeatures.Add(newWaveFeature)
 
			End If
 
		Next
 
	End Sub
 
	Private Function IsWaveFeature(ByVal theFeature As Features.Feature) As Boolean
 
		Dim wave2 As Boolean = False
 
		'check for wave linked sketch
		'linked sketches can be internal to another feature (such as an extrude)
		'so check for a WaveSketch feature before running the .IsInternal check
		If TypeOf (theFeature) Is NXOpen.Features.WaveSketch Then
			wave2 = Me.IsWaveFeature2(theFeature)
			Return True
		End If
 
		'some features create links within the part file (extract face, instance geometry, etc)
		'if the feature .IsInternal, odds are good it links to something in this part file
		'and not an external file
		If theFeature.IsInternal Then
			wave2 = Me.IsWaveFeature2(theFeature)
 
			'skip features such as "mirror geometry" or "instance geometry" that do not link to another part
			Return False
		End If
 
		'check for wave linked datum
		If TypeOf (theFeature) Is NXOpen.Features.WaveDatum Then
			wave2 = Me.IsWaveFeature2(theFeature)
 
			Return True
		End If
 
		'check for wave linked point
		If TypeOf (theFeature) Is NXOpen.Features.WavePoint Then
			wave2 = Me.IsWaveFeature2(theFeature)
 
			Return True
		End If
 
		'check for wave linked curve
		If TypeOf (theFeature) Is NXOpen.Features.CompositeCurve AndAlso theFeature.FeatureType = "LINKED_CURVE" Then
			wave2 = Me.IsWaveFeature2(theFeature)
 
			Return True
		End If
 
		'check for wave linked face
		If TypeOf (theFeature) Is NXOpen.Features.ExtractFace AndAlso theFeature.FeatureType = "LINKED_FACE" Then
			wave2 = Me.IsWaveFeature2(theFeature)
 
			Return True
		End If
 
		'check for wave linked region
		If TypeOf (theFeature) Is NXOpen.Features.ExtractFace AndAlso theFeature.FeatureType = "LINKED_REGION" Then
			Return True
		End If
 
		'check for wave linked body
		If TypeOf (theFeature) Is NXOpen.Features.ExtractFace AndAlso theFeature.FeatureType = "LINKED_BODY" Then
			wave2 = Me.IsWaveFeature2(theFeature)
 
			Return True
		End If
 
		'check for wave linked mirror body
		If TypeOf (theFeature) Is NXOpen.Features.MirrorBody AndAlso theFeature.FeatureType = "LINKED_MIRROR" Then
			Return True
		End If
 
		'check for wave linked routing object
		If TypeOf (theFeature) Is NXOpen.Features.WaveRouting Then
			wave2 = Me.IsWaveFeature2(theFeature)
 
			Return True
		End If
 
		'none of the above...
		Return False
 
	End Function
 
	Private Function IsWaveFeature2(ByVal theFeature As Features.Feature) As Boolean
 
		Dim lw As ListingWindow = cSession.ListingWindow
		lw.Open()
 
		'lw.WriteLine("feature: " & theFeature.GetFeatureName)
		'lw.WriteLine("owning part: " & theFeature.OwningPart.Leaf)
 
		Dim theSourceEntityTag As NXOpen.Tag = NXOpen.Tag.Null
		Dim owningSourcePartTag As Tag = NXOpen.Tag.Null
		Dim allowLoad As Boolean = True
		Dim owningPartName As String = ""
 
 
		Try
			'.AskLinkSource throws error if link is internal to the part being processed
			'(simple hole, mirror geometry)
			cUfSession.Wave.AskLinkSource(theFeature.Tag, allowLoad, theSourceEntityTag)
			cUfSession.Obj.AskOwningPart(theSourceEntityTag, owningSourcePartTag)
			cUfSession.Part.AskPartName(owningSourcePartTag, owningPartName)
 
 
		Catch ex As NXException
			If ex.ErrorCode = 1105004 Then
				'first parameter passed in was invalid (not linked to external geometry?)
				'lw.WriteLine("NX exception: " & ex.ErrorCode & ", " & ex.Message)
				'lw.WriteLine("")
				Return False
			Else
				'lw.WriteLine("NX exception: " & ex.ErrorCode & ", " & ex.Message)
				'lw.WriteLine("")
				Return False
			End If
		Catch ex As Exception
			lw.WriteLine("Exception: " & ex.Message)
			lw.WriteLine("")
		End Try
 
		'lw.WriteLine("source part: " & owningPartName)
		'lw.WriteLine("current part: " & theFeature.OwningPart.FullPath)
		'lw.WriteLine("")
 
 
		If owningPartName.ToUpper = theFeature.OwningPart.FullPath.ToUpper Then
		
			'lw.WriteLine("IsWaveFeature2: False")
			'lw.WriteLine("")
 			Return False
			
		Else
			'lw.WriteLine("IsWaveFeature2: True")
			'lw.WriteLine("") 
			Return True
 
		End If
 
		'lw.Close()
 
 
	End Function
 
	Private Sub FindUniqueParents()
 
		For Each tempWF As WaveFeature In Me.WaveFeatures
		
			If tempWF.IsBroken Then
			
				cBrokenLinks.Add(tempWF)
				
			End If
			
			For Each tempString As String In tempWF.WaveParents
			
				If Not cUniqueWaveParents.Contains(tempString) Then
				
					cUniqueWaveParents.Add(tempString)
					
				End If
				
			Next
			
		Next
 
		cUniqueWaveParents.Sort()
 
	End Sub
 
End Class
 
 
Public Class WaveFeature
 
	Private cSession As Session = Session.GetSession
	Private cUfSession As UFSession = UFSession.GetUFSession
 
	Private cFeature As Features.Feature
	Public Property Feature() As Features.Feature
		Get
			Return cFeature
		End Get
		Set(ByVal value As Features.Feature)
			cFeature = value
			Me.ExamineFeature()
		End Set
	End Property
 
	Private cParents As New List(Of String)
	Public ReadOnly Property WaveParents() As List(Of String)
		Get
			Return cParents
		End Get
	End Property
 
	Private cIsBroken As Boolean = True   'assume link is broken
	Public ReadOnly Property IsBroken() As Boolean
		Get
			Return cIsBroken
		End Get
	End Property
 
	Private cIsAccepted As Boolean = False  'assume it is not broken intentionally
	Public ReadOnly Property IsAccepted() As Boolean
		Get
			Return cIsAccepted
		End Get
	End Property
 
 
	Public Sub New(ByVal theFeature As Features.Feature)
 
		Me.Feature = theFeature
 
	End Sub
 
	Private Sub ExamineFeature()
 
		Dim sourcePart As String = ""
		Dim sourceId As String = ""
 
		cUfSession.Wave.IsLinkBroken(cFeature.Tag, cIsBroken)
 
		If cIsBroken Then
		
			cIsBroken = True
			cUfSession.Wave.AskBrokenLinkSourcePart(cFeature.Tag, sourcePart, sourceId)
			cParents.Add(sourcePart)
 
			cUfSession.Wave.AskLinkAcceptBroken(cFeature.Tag, cIsAccepted)
 
		Else
			'link NOT broken
 
			'ref: nx_api4930
			Dim theInfo As UFWave.LinkedFeatureInfo
			cUfSession.Wave.AskLinkedFeatureInfo(cFeature.Tag, theInfo)
			Dim sources() As String = theInfo.source_part_name.Split(",")
 
			'wave feature may have multiple parents; e.g. the mirror body
			'  mirror plane may be owned by a file other than the file that owns the body
			For Each prtSource As String In sources
				cParents.Add(prtSource)
			Next
 
		End If
 
	End Sub
 
End Class 

With best regards
Michael

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Eng-Tips Forums free from inappropriate posts.
The Eng-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Eng-Tips forums is a member-only feature.

Click Here to join Eng-Tips and talk with other members! Already a Member? Login


Resources

White Paper - How ESI is Helping Move New Medical Device Product to Market Quicker & More Cost Effic
Early Supplier Involvement has long been a strategy employed by manufacturers to produce innovative products. Now, it almost seems like a necessity. Because decisions made in the design phase can positively affect product quality and costs, this can help add value to OEM bottom lines. This white paper will discuss many facets of ESI, including why it’s so valuable today, what challenges limit the benefits of ESI, how cost is impacted, and more. Download Now
White Paper - Moving to a Driverless Future
This white paper describes what we see as the best practices to support a sustainable engineering process for autonomous vehicle design. It exposes how to use simulation and testing in common frameworks to enable design exploration, verification and validation for the development of autonomous cars at a system, software and full-vehicle level to drive a mature product development process for automated driving. Download Now
Research Report - How Engineers are Using Remote Access
Remote access enables engineers to work from anywhere provided they have an internet connection. We surveyed our audience of engineers, designers and product managers to learn how they use remote access within their organizations. We wanted to know which industries have adopted remote access, which software they are using, and what features matter most. Download Now

Close Box

Join Eng-Tips® Today!

Join your peers on the Internet's largest technical engineering professional community.
It's easy to join and it's free.

Here's Why Members Love Eng-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close