diff --git a/CatiaNetTest/AssemblyTiers2.vb b/CatiaNetTest/AssemblyTiers2.vb index 60db50de2baab87b1ce628dc1e3b912c4cd9f3ba..12ba79388607cd589ae079c7c529301165ba5771 100644 --- a/CatiaNetTest/AssemblyTiers2.vb +++ b/CatiaNetTest/AssemblyTiers2.vb @@ -574,7 +574,7 @@ exit2: End If 'recalculate assembly boundaries and removal distances - RecalculateRemovalDistances(cRelevantProducts, cDeactivated) + RecalculateRemovalDistances(cRelevantProducts, bDeactivated) 'if there are still parts to disassemble... If intI >= cBaseProducts.Count Then @@ -1316,7 +1316,7 @@ exitCD: Dim TheMeasurable - Debug.Print("Extremum coordinates in the local Axis System:") + Debug.Print("Global coordinates of local extrema:") 'Transform local extrema coordinates into global coordinates and update aAssemblyBoundaries @@ -1448,22 +1448,21 @@ exitCD: End Function - Sub RecalculateRemovalDistances(cRelProd As ArrayList, cDeact As ArrayList) + Sub RecalculateRemovalDistances(cRelProd As ArrayList, bDeact As Boolean()) Dim aRemovalDistances(cRelProd.Count - 1, 5) Dim i As Integer Dim relProd As Product 'assure that the origin is inside the BB of assembly - aAssemblyBoundaries(0) = 0# - aAssemblyBoundaries(1) = 0# - aAssemblyBoundaries(2) = 0# - aAssemblyBoundaries(3) = 0# - aAssemblyBoundaries(4) = 0# - aAssemblyBoundaries(5) = 0# + aAssemblyBoundaries(0) = -1 / 0 + aAssemblyBoundaries(1) = 1 / 0 + aAssemblyBoundaries(2) = -1 / 0 + aAssemblyBoundaries(3) = 1 / 0 + aAssemblyBoundaries(4) = -1 / 0 + aAssemblyBoundaries(5) = 1 / 0 For i = 0 To cRelProd.Count - 1 - relProd = cRelProd.Item(i) - If Not productIsInCollection(relProd, cDeact) Then + If Not bDeact(i) Then If aInitPos(i, 9) + aPartBBGlob(i, 0) > aAssemblyBoundaries(0) Then aAssemblyBoundaries(0) = aInitPos(i, 9) + aPartBBGlob(i, 0) End If @@ -1486,8 +1485,7 @@ exitCD: Next i For i = 0 To cRelProd.Count - 1 - relProd = cRelProd.Item(i) - If Not productIsInCollection(relProd, cDeact) Then + If Not bDeact(i) Then aRemovalDistances(i, 0) = aAssemblyBoundaries(0) - aPartBBGlob(i, 1) aRemovalDistances(i, 1) = aAssemblyBoundaries(1) - aPartBBGlob(i, 0) aRemovalDistances(i, 2) = aAssemblyBoundaries(2) - aPartBBGlob(i, 3) diff --git a/CatiaNetTest/AssemblyTiers3.vb b/CatiaNetTest/AssemblyTiers3.vb new file mode 100644 index 0000000000000000000000000000000000000000..07773ff8fcecd98681931741cbfd71743b5eca41 --- /dev/null +++ b/CatiaNetTest/AssemblyTiers3.vb @@ -0,0 +1,2024 @@ +Imports System +Imports HybridShapeTypeLib +Imports INFITF +Imports MECMOD +Imports NavigatorTypeLib +Imports ProductStructureTypeLib +Imports SPATypeLib +Imports PARTITF +Imports Microsoft.Office.Interop.Excel + +Public Class AssemblyTiers3 + Inherits Form + + Friend WithEvents OKButton As System.Windows.Forms.Button = New System.Windows.Forms.Button() + Friend WithEvents BBCodeComboBox As System.Windows.Forms.ComboBox = New ComboBox() + Friend WithEvents BBPCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox() + Friend WithEvents CCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox() + Friend WithEvents AutoStepCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox() + Friend WithEvents StepTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox() + Friend WithEvents CollSensTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox() + Friend WithEvents ExtractDirCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox() + Friend WithEvents AxisComboBox As System.Windows.Forms.ComboBox = New System.Windows.Forms.ComboBox() + Friend WithEvents XLSTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox() + + Public bConnectivityCheck As Boolean + Public bBoundingBoxProjectionCheck As Boolean + Public bAutomaticStep As Boolean + Public bChooseExtractionDirection As Boolean + Public intJ As Integer + Public iBoundingBoxCode As Integer + Public intStep As Integer + Public dCollSens As Double + Public xlsPath As String + Public xlsFileName As String + Public intParts As Integer + Public intNumFaces As Integer + Public primaryFasteners As New ArrayList + Public secondaryFasteners As New ArrayList + Public cAllProducts As New ArrayList + Public cRelevantProducts As New ArrayList + Public cBaseProducts As New ArrayList + Public aRemovalDistances(,) As Double + Public aAssemblyBoundaries(5) As Double + Public aPartBBGlob(,) As Double + Public aInitPos(,) As Double + Public liaisonMatrix(,) As Integer + Public sChosenDirection As String + Public oList As Object + Public CATIA As INFITF.Application + + + Sub CatMain() + + ''Test parameters + 'iBoundingBoxCode = 1 + 'bBoundingBoxProjectionCheck = True + 'bConnectivityCheck = False + 'bAutomaticStep = False + 'intStep = 5 + 'dCollSens = 2 + 'bChooseExtractionDirection = False + ''number of analysed disassembly directions + ''6 - only global axes, 12 - including local axes + 'intJ = 6 + xlsPath = "D:\mikep\Files\RWTH\Master Produktionstechnik\Masterarbeit\Experimente\Protocols\" + 'xlsFileName = "Centrifugal pump 5mm step" + + CATIA = GetObject(, "CATIA.Application") + If CATIA Is Nothing Then CATIA = CreateObject("CATIA.Application") + + Debug.Print("========================================================") + + Dim document As ProductDocument + document = CATIA.ActiveDocument + + 'Extraction of all "leaf" products to cAllProducts + ExtractProducts(document.Product) + + 'Collection of "leaf" Products (without nested Products) + Dim oInstances As New ArrayList + oInstances = cAllProducts + Dim i As Integer + Dim outputText As String + + intParts = oInstances.Count + outputText = "This assembly contains " + CStr(intParts) + " parts" + vbNewLine + MsgBox(outputText) + + 'Select the assembly's base components + 'Declare selection + Dim oSel As Selection + Dim baseSel As Object 'to deal with restricted function problem + oSel = CATIA.ActiveDocument.Selection + baseSel = oSel + 'Create an array for CATParts + Dim strArray(0) + strArray(0) = "Part" + 'Display a messagebox prompting the user to select CATIA parts + MsgBox("Please select the assembly's base components") + Dim sStatus As String + sStatus = baseSel.SelectElement3(strArray, "Select parts", False, INFITF.CATMultiSelectionMode.CATMultiSelTriggWhenUserValidatesSelection, False) + + For i = 1 To baseSel.Count + cBaseProducts.Add(baseSel.Item(i).LeafProduct) + Debug.Print("Added base component: " & baseSel.Item(i).LeafProduct.Name) + Next + + oSel.Clear() + baseSel.Clear + + 'Separation of components + DeactivateFasteners(document.Product) + + 'Display the number of relevant parts + outputText = CStr(cRelevantProducts.Count) + " parts are considered in precedence graph generation" + MsgBox(outputText) + + 'Distances from global axis system origin to assembly boundary (along global axis) + aAssemblyBoundaries(0) = -1 / 0 'max_X + aAssemblyBoundaries(1) = 1 / 0 'min_X + aAssemblyBoundaries(2) = -1 / 0 'max_Y + aAssemblyBoundaries(3) = 1 / 0 'min_Y + aAssemblyBoundaries(4) = -1 / 0 'max_Z + aAssemblyBoundaries(5) = 1 / 0 'min_Z + + 'Global coordinates, of which at least one has to be exceeded by the part origin, for that part to be "disassembled" + 'in global axis directions + ReDim aRemovalDistances(cRelevantProducts.Count - 1, 5) + aRemovalDistances(0, 0) = 0# 'X_pos + aRemovalDistances(0, 1) = 0# 'X_neg + aRemovalDistances(0, 2) = 0# 'Y_pos + aRemovalDistances(0, 3) = 0# 'Y_neg + aRemovalDistances(0, 4) = 0# 'Z_pos + aRemovalDistances(0, 5) = 0# 'Z_neg + + 'Store information about secondary BB (6 distances to boundary planes from part origin along global x/y/z directions) - used to define aRemovalDistances + 'Secondary BB: faces parallel to global origin planes and defined by outermost corner points of local BB of this part + ReDim aPartBBGlob(cRelevantProducts.Count - 1, 5) + aPartBBGlob(0, 0) = 0# 'x_part_glob_pos + aPartBBGlob(0, 1) = 0# 'x_part_glob_neg + aPartBBGlob(0, 2) = 0# 'y_part_glob_pos + aPartBBGlob(0, 3) = 0# 'y_part_glob_neg + aPartBBGlob(0, 4) = 0# 'z_part_glob_pos + aPartBBGlob(0, 5) = 0# 'z_part_glob_neg + + 'Initialize aPartBBGlob with safe values + For i = 0 To cRelevantProducts.Count - 1 + aPartBBGlob(i, 0) = -1 / 0 + aPartBBGlob(i, 1) = 1 / 0 + aPartBBGlob(i, 2) = -1 / 0 + aPartBBGlob(i, 3) = 1 / 0 + aPartBBGlob(i, 4) = -1 / 0 + aPartBBGlob(i, 5) = 1 / 0 + Next + + Dim BBStartTime As DateTime + BBStartTime = Now + + 'This is used to check whether a product must be moved in current iteration + Dim bMoveable(cRelevantProducts.Count - 1) As Boolean + + 'Number of faces in assembly represents the geometrical complexity of parts + intNumFaces = 0 + + For i = 0 To cRelevantProducts.Count - 1 + Dim prodI As Product + If iBoundingBoxCode = 1 Then + 'this won't work if part document name is not = part number + prodI = cRelevantProducts.Item(i) + Dim docName As String + docName = prodI.PartNumber + ".CATPart" + Debug.Print(">>> " & docName & " <<<") + GenerateBoundingBox(CATIA.Documents.Item(docName), prodI, i) + ElseIf iBoundingBoxCode = 2 Then + prodI = cRelevantProducts.Item(i) + Dim docName As String + docName = prodI.PartNumber + ".CATPart" + Dim oPartDoc As PartDocument + Dim sPartPath As String + sPartPath = prodI.GetMasterShapeRepresentationPathName + oPartDoc = CATIA.Documents.Read(sPartPath) + Debug.Print(">>> " & docName & " <<<") + 'CATIA.Documents.Item(docName) + GenerateBoundingBox(oPartDoc, prodI, i) + Else + Debug.Print("Allowed bounding box code type are 1 and 2!") + End If + + 'Base component is in cRelevantProducts, but not moveable + If productIsInCollection(prodI, cBaseProducts) Then + bMoveable(i) = False + Else + bMoveable(i) = True + End If + + Next i + + Dim BBMillisecondsElapsed As Double + BBMillisecondsElapsed = (Now - BBStartTime).TotalMilliseconds + Dim BBSecondsElapsed As Double + BBSecondsElapsed = Math.Round(BBMillisecondsElapsed / 1000.0, 2) + MsgBox("Bounding box calculation took " & CStr(BBSecondsElapsed) & " seconds") + Debug.Print("Number of faces in assembly: " & CStr(intNumFaces)) + + 'Export BB volumes of parts to Excel + ExportBBVolumes() + + 'Collision parameters + If bAutomaticStep Then + Dim dGeomMean As Double + dGeomMean = (aAssemblyBoundaries(0) - aAssemblyBoundaries(1)) * (aAssemblyBoundaries(2) - aAssemblyBoundaries(3)) * (aAssemblyBoundaries(4) - aAssemblyBoundaries(5)) + dGeomMean = dGeomMean ^ (1 / 3) + intStep = Math.Round(dGeomMean / 50, 0) + End If + Debug.Print("Movement step: " & CStr(intStep)) + + MsgBox("Assembly dimensions: " & vbNewLine & + "X = " & aAssemblyBoundaries(0) - aAssemblyBoundaries(1) & vbNewLine & + "Y = " & aAssemblyBoundaries(2) - aAssemblyBoundaries(3) & vbNewLine & + "Z = " & aAssemblyBoundaries(4) - aAssemblyBoundaries(5)) + + 'After the aAssemblyBoundaries and aPartBBGlob are calculated, define aRemovalDistances + For i = 0 To cRelevantProducts.Count - 1 + aRemovalDistances(i, 0) = aAssemblyBoundaries(0) - aPartBBGlob(i, 1) + aRemovalDistances(i, 1) = aAssemblyBoundaries(1) - aPartBBGlob(i, 0) + aRemovalDistances(i, 2) = aAssemblyBoundaries(2) - aPartBBGlob(i, 3) + aRemovalDistances(i, 3) = aAssemblyBoundaries(3) - aPartBBGlob(i, 2) + aRemovalDistances(i, 4) = aAssemblyBoundaries(4) - aPartBBGlob(i, 5) + aRemovalDistances(i, 5) = aAssemblyBoundaries(5) - aPartBBGlob(i, 4) + Next i + + 'MsgBox("Removal distances for " & cRelevantProducts.Item(1).PartNumber & ":" & vbNewLine & + '"X_pos = " & aRemovalDistances(0, 0) & vbNewLine & + '"X_neg = " & aRemovalDistances(0, 1) & vbNewLine & + '"Y_pos = " & aRemovalDistances(0, 2) & vbNewLine & + '"Y_neg = " & aRemovalDistances(0, 3) & vbNewLine & + '"Z_pos = " & aRemovalDistances(0, 4) & vbNewLine & + '"Z_neg = " & aRemovalDistances(0, 5)) + + '#################### Main algorithm ########################## + + Dim intI As Integer 'total number of components in the scene minus base parts + Dim intTier As Integer 'number of current assembly tier + Dim int_i As Integer 'product index in cRelevantProducts + Dim int_i_cycle As Integer 'product counter + Dim int_j As Integer 'primary direction index 1..12 + Dim int_j_temp As Integer 'used to display movement direction once + Dim int_k As Integer 'secondary direction index 1..10 + Dim total_coll As Long 'counter of total collision detections + Dim cDeactivated As New ArrayList 'really deactivated products + Dim cVirtual As Collection 'these funny green parts + Dim precedenceMatrix(cRelevantProducts.Count - 1, cRelevantProducts.Count - 1) As Single + Dim disassDir(cRelevantProducts.Count - 1, 11) + Dim aTiers(cRelevantProducts.Count - 1) As Integer + ReDim aInitPos(cRelevantProducts.Count - 1, 11) 'remember initial positions of the products + Dim bInitPosRecorded(cRelevantProducts.Count - 1) As Boolean + Dim bDeactivated(cRelevantProducts.Count - 1) As Boolean + Dim bDisassembled(cRelevantProducts.Count - 1) As Boolean + + For i = 0 To cRelevantProducts.Count - 1 + If intJ = 6 Then + For j = 0 To 5 + disassDir(i, j) = 1 + Next + End If + If intJ = 12 Then + For j = 0 To 11 + disassDir(i, j) = 1 + Next + End If + Next + + 'Before trying to remove a component, check whether it would break liaison graph connectivity + Dim connectivityCheckNodeIndices As New List(Of Integer) + If bConnectivityCheck Then + Dim componentIndex As Integer + componentIndex = 0 + For Each oComponent In cRelevantProducts + connectivityCheckNodeIndices.Add(componentIndex) + componentIndex = componentIndex + 1 + Next oComponent + 'Liaison graph extraction for connectivity checks + Liaison() + End If + + intI = cRelevantProducts.Count 'the index of base components will be simply skipped (cRelevantProducts includes cBaseProducts, unlike in the paper!) + intTier = 1 'counts current disassembly tier (lower number means earlier disassembly possible) - this gets reversed in the end + int_i = 0 'index of current part in collection of relevant products + int_i_cycle = 0 'counter for the current tier iteration + int_j = 0 'index of disassembly direction + int_j_temp = -1 'used to display movement direction once + total_coll = 0 + + 'map indices to directions (careful, starts from 0 here, but the paper and moveProduct uses 1 as start) + Dim d1 + d1 = CreateObject("Scripting.Dictionary") + d1.Add(0, "Global X+") + d1.Add(1, "Global Y+") + d1.Add(2, "Global Z+") + d1.Add(3, "Global X-") + d1.Add(4, "Global Y-") + d1.Add(5, "Global Z-") + d1.Add(6, "Local X+") + d1.Add(7, "Local Y+") + d1.Add(8, "Local Z+") + d1.Add(9, "Local X-") + d1.Add(10, "Local Y-") + d1.Add(11, "Local Z-") + + 'access the clash technology object + Dim cClashes As Clashes + cClashes = CATIA.ActiveDocument.Product.GetTechnologicalObject("Clashes") + 'access the groups technology object + Dim cGroups As Groups + cGroups = CATIA.ActiveDocument.Product.GetTechnologicalObject("Groups") + + Dim AssemblyTiersStartTime As DateTime + AssemblyTiersStartTime = Now + + While intI > cBaseProducts.Count 'tier loop + While int_i_cycle < intI - cBaseProducts.Count 'part loop + 'Processing next Product + Dim product1 As Product + product1 = cRelevantProducts.Item(int_i) + 'Remember initial position P_i (initPos) + Dim initPos(11) + Dim oPosition1 As Object + oPosition1 = product1.Position + oPosition1.GetComponents(initPos) + If bInitPosRecorded(int_i) = False Then + Dim ip As Integer + For ip = 0 To 11 + aInitPos(int_i, ip) = initPos(ip) + Next ip + bInitPosRecorded(int_i) = True + End If + If bMoveable(int_i) = True Then + Debug.Print("[tier=" & intTier & ", i_cycle=" & int_i_cycle & ", I=" & intI & "] Processing part: " & product1.Name) + Dim connected As Boolean + connected = False + If bConnectivityCheck = True Then + Dim listIndex As Integer + listIndex = 0 + For Each partIndex In connectivityCheckNodeIndices + If partIndex = int_i Then + Exit For + Else + listIndex = listIndex + 1 + End If + Next + connectivityCheckNodeIndices.RemoveAt(listIndex) + 'Check whether all node of LG can be visited from any other node (= connected graph) + If SubassemblyIsConnected(connectivityCheckNodeIndices) Then + 'Put int_i back at listIndex + connectivityCheckNodeIndices.Insert(listIndex, int_i) + connected = True + Else + 'If connectivity will be broken, skip this component + Debug.Print("Removing " & product1.Name & " would violate liaison graph connectivity!") + 'Put int_i back at listIndex + connectivityCheckNodeIndices.Insert(listIndex, int_i) + End If + Else 'no connectivity check, connectivity is assumed to hold + connected = True + End If + If connected = True Then + 'Group that includes our product (needed for collision detection between two selections or groups) + Dim group1 As Group + group1 = cGroups.Add + group1.AddExplicit(product1) + 'Create a Group of Products that this product shouldn't collide with + Dim group2 As Group + group2 = cGroups.Add + Dim iStaticProduct As Integer + For iStaticProduct = 0 To cRelevantProducts.Count - 1 + If iStaticProduct <> int_i And Not bDeactivated(iStaticProduct) Then + If bBoundingBoxProjectionCheck Then + If BoundingBoxesOverlap(int_i, iStaticProduct) Then + group2.AddExplicit(cRelevantProducts.Item(iStaticProduct)) + End If + Else + group2.AddExplicit(cRelevantProducts.Item(iStaticProduct)) + End If + End If + Next iStaticProduct + While int_j < intJ 'direction loop + While productReachedFinalPosition(product1, int_i) = False 'movement loop + moveProduct(product1, int_j, True) + If productReachedFinalPosition(product1, int_i) = True Then + bDisassembled(int_i) = True + Debug.Print("Successful disassembly: [" & d1.Item(int_j) & "]") + End If + If collisionDetected(cClashes, group1, group2) = True Then + 'check for collisions with higher tier + Dim detConflicts As Conflicts + detConflicts = cClashes.Item(cClashes.Count).Conflicts + If detConflicts.Count > 0 Then + Dim oConflict1 As Conflict + Dim ic As Integer + For ic = 1 To detConflicts.Count + oConflict1 = detConflicts.Item(ic) + oConflict1.Status = SPATypeLib.CatConflictStatus.catConflictStatusRelevant + If oConflict1.Type = SPATypeLib.CatConflictType.catConflictTypeClash Then + If oConflict1.Value < -dCollSens Then + Dim secProduct As Product + 'get the product we collided with + secProduct = oConflict1.SecondProduct + 'find the tier of the second product + Dim dummyProd As Product + Dim iIndex As Integer + iIndex = 0 + For Each dummyProd In cRelevantProducts + If dummyProd.Name = secProduct.Name Then + Exit For + End If + iIndex = iIndex + 1 + Next dummyProd + Dim secTier As Integer + secTier = aTiers(iIndex) + 'as soon as secTier is not the direct higher tier, no reason to move further + If secTier < intTier - 1 Or (intTier = 1 And secTier = 0) Then + disassDir(int_i, int_j) = 0 + 'move product to initial position + Dim oPosition3 As Object + oPosition3 = product1.Position + oPosition3.SetComponents(initPos) + Exit While + End If + 'if the disassembly tier is 1 lower (attention: tiers get reversed in the end to the assembly tiers!) + If secTier = intTier - 1 And Not intTier = 1 Then + 'Debug.Print("Collision with higher tier: " & oConflict1.FirstProduct.Name & " - " & oConflict1.SecondProduct.Name & " = " & oConflict1.Value) + 'record precedence relation, because secProduct is an obstacle in the way of the current product + precedenceMatrix(int_i, iIndex) = 1 + 'move the product through the "virtual" part from higher tier + End If + End If 'deeper than dCollSens + End If 'clash + Next ic 'next conflict + End If + End If + End While 'movement loop + 'move product to initial position + Dim oPosition4 As Object + oPosition4 = product1.Position + oPosition4.SetComponents(initPos) + 'take next direction + int_j += 1 + End While 'direction loop + 'if this component can be disassembled, remove its index from connectivity check list + If bConnectivityCheck And bDisassembled(int_i) Then + Dim listInd As Integer + listInd = 0 + For Each partIndex In connectivityCheckNodeIndices + If partIndex = int_i Then + Exit For + Else + listInd = listInd + 1 + End If + Next partIndex + 'Remove int_i from index list (only after all directions were checked) + connectivityCheckNodeIndices.RemoveAt(listInd) + End If + End If + int_i_cycle += 1 + Else + 'base component or deactivated + Debug.Print("Skipping " + product1.Name + " (base component or deactivated)") + End If + int_i += 1 + int_j = 0 + End While 'part loop + + Dim p As Integer + Dim intItemp As Integer + intItemp = intI + 'record tiers + For p = 0 To cRelevantProducts.Count - 1 + If productIsInCollection(cRelevantProducts.Item(p), cBaseProducts) Then + 'base product always has tier 0 (doesn't get reversed) + aTiers(p) = 0 + Else + 'not a base product + 'product has valid disass. directions and has no tier recorded yet + If bDisassembled(p) = True And Not aTiers(p) > 0 Then + 'save tier + aTiers(p) = intTier + 'decrease the counter of active products in assembly + intI = intI - 1 + 'change visuals for "virtual" products + Dim virtSelection As Selection + virtSelection = document.Selection + virtSelection.Clear() + virtSelection.Add(cRelevantProducts.Item(p)) + Dim visProperties1 As Object + visProperties1 = virtSelection.VisProperties + visProperties1.SetRealColor(80, 255, 160, 1) + virtSelection.Clear() + 'remember virtual green products + 'cVirtual.Add cRelevantProducts.Item(p) + 'fix position + bMoveable(p) = False + + End If + 'product from higher tier + If bDisassembled(p) = True And aTiers(p) = intTier - 1 And intTier > 1 Then + 'deactivate + Dim selection2 As Selection + selection2 = CATIA.ActiveDocument.Selection + selection2.Clear() + selection2.Add(cRelevantProducts.Item(p)) + CATIA.StartCommand("Activate / Deactivate Component") + selection2.Clear() + cDeactivated.Add(cRelevantProducts.Item(p)) + bDeactivated(p) = True + End If + End If + Next p + + 'Deactivate last disassembly tier directly + For p = 0 To cRelevantProducts.Count - 1 + If intI = cBaseProducts.Count And aTiers(p) = intTier Then + Dim selektion As Selection + selektion = CATIA.ActiveDocument.Selection + selektion.Clear() + selektion.Add(cRelevantProducts.Item(p)) + CATIA.StartCommand("Activate / Deactivate Component") + selektion.Clear() + cDeactivated.Add(cRelevantProducts.Item(p)) + bDeactivated(p) = True + End If + Next p + + 'Notify the user if no parts could be disassembled in this tier + If intI = intItemp Then + Debug.Print("WARNING! No parts could be removed during this cycle." & vbNewLine & "This is usually due to inaccuracies in modelling (e.g. collisions in initial assembly).") + For p = 0 To cRelevantProducts.Count - 1 + If aTiers(p) = 0 And Not productIsInCollection(cRelevantProducts.Item(p), cBaseProducts) Then + Dim selektion As Selection + selektion = CATIA.ActiveDocument.Selection + selektion.Clear() + selektion.Add(cRelevantProducts.Item(p)) + CATIA.StartCommand("Activate / Deactivate Component") + selektion.Clear() + cDeactivated.Add(cRelevantProducts.Item(p)) + bDeactivated(p) = True + End If + Next p + Exit While + End If + + 'recalculate assembly boundaries and removal distances + RecalculateRemovalDistances(cRelevantProducts, bDeactivated) + + intTier += 1 + int_i = 0 + int_i_cycle = 0 + + End While + + Dim SecondsElapsed As Double + Dim MillisecondsElapsed As Double + MillisecondsElapsed = (Now - AssemblyTiersStartTime).TotalMilliseconds + SecondsElapsed = Math.Round(MillisecondsElapsed / 1000.0, 2) + MsgBox("Collision detection algorithm finished execution after " & CStr(SecondsElapsed) & " seconds") + + 'Return products to their initial positions, activate them + Dim p1 As Integer + For p1 = 0 To cRelevantProducts.Count - 1 + If Not productIsInCollection(cRelevantProducts.Item(p1), cBaseProducts) Then + Dim oPosition4 As Object + oPosition4 = cRelevantProducts.Item(p1).Position + Dim aPos(11) + For comp = 0 To 11 + aPos(comp) = aInitPos(p1, comp) + Next comp + oPosition4.SetComponents(aPos) + Dim selection4 As Selection + selection4 = CATIA.ActiveDocument.Selection + selection4.Clear() + selection4.Add(cRelevantProducts.Item(p1)) + CATIA.StartCommand("Activate / Deactivate Component") + selection4.Clear() + End If + Next p1 + + 'Select a single extraction direction in case there are multiple + Dim d2 + d2 = CreateObject("Scripting.Dictionary") + d2.Add("Global X+", 0) + d2.Add("Global Y+", 1) + d2.Add("Global Z+", 2) + d2.Add("Global X-", 3) + d2.Add("Global Y-", 4) + d2.Add("Global Z-", 5) + d2.Add("Local X+", 6) + d2.Add("Local Y+", 7) + d2.Add("Local Z+", 8) + d2.Add("Local X-", 9) + d2.Add("Local Y-", 10) + d2.Add("Local Z-", 11) + 'Inverse axis indices + Dim d3 + d3 = CreateObject("Scripting.Dictionary") + d3.Add(0, 3) + d3.Add(1, 4) + d3.Add(2, 5) + d3.Add(3, 0) + d3.Add(4, 1) + d3.Add(5, 2) + d3.Add(6, 9) + d3.Add(7, 10) + d3.Add(8, 11) + d3.Add(9, 6) + d3.Add(10, 7) + d3.Add(11, 8) + For int_i = 0 To cRelevantProducts.Count - 1 + If bChooseExtractionDirection Then + Dim sum As Integer + sum = 0 + For intAxis = 0 To intJ - 1 + sum = sum + disassDir(int_i, intAxis) + Next intAxis + 'Only for products with multiple extraction directions + If sum > 1 Then + 'Add options to ComboBox + For intAxis = 0 To intJ - 1 + If disassDir(int_i, intAxis) = 1 Then + 'ExtractionDirection.ComboBox1.AddItem(d1.Item(intAxis)) + End If + Next intAxis + 'Highlight the product in CATIA + Dim selection5 As Selection + selection5 = CATIA.ActiveDocument.Selection + selection5.Clear() + selection5.Add(cRelevantProducts.Item(int_i + 1)) + 'Show dialog + 'ExtractionDirection.Show + selection5.Clear() + 'Translate chosen axis name back into index 0..11 + Dim iChosenDir As Integer + iChosenDir = d2.Item(sChosenDirection) + 'Set all other disassembly directions to 0 + For intAxis = 0 To intJ - 1 + If intAxis = iChosenDir Then + disassDir(int_i, intAxis) = 1 + Else + disassDir(int_i, intAxis) = 0 + End If + Next intAxis + End If + End If + 'Reverse tier values + Dim intMaxTier As Integer + intMaxTier = intTier - 1 + If aTiers(int_i) <> 0 Then + aTiers(int_i) = intMaxTier + 1 - aTiers(int_i) + End If + 'Reverse disassembly axis (assembly axis = -disass. axis) + For intAxis = 0 To intJ - 1 + If disassDir(int_i, intAxis) = 1 Then + disassDir(int_i, intAxis) = 0 + disassDir(int_i, d3.Item(intAxis)) = 1 + End If + Next intAxis + Next int_i + + 'Association of components belonging to sequential tiers + + Dim cClashes1 As Clashes + Dim oClash1 As Clash + oClash1 = cClashes.Add + oClash1.ComputationType = CatClashComputationType.catClashComputationTypeBetweenAll + oClash1.InterferenceType = CatClashInterferenceType.catClashInterferenceTypeContact + oClash1.Compute() + Dim cInitConflicts As Conflicts + cInitConflicts = oClash1.Conflicts + Dim initConfl As Conflict + Dim nConfl As Integer + nConfl = 0 + For Each initConfl In cInitConflicts + Dim firstIndex As Integer + Dim secondIndex As Integer + firstIndex = GetProductIndex(initConfl.FirstProduct, cRelevantProducts) + secondIndex = GetProductIndex(initConfl.SecondProduct, cRelevantProducts) + If aTiers(firstIndex) = aTiers(secondIndex) - 1 Then + precedenceMatrix(firstIndex, secondIndex) = 1 + End If + If aTiers(secondIndex) = aTiers(firstIndex) - 1 Then + precedenceMatrix(secondIndex, firstIndex) = 1 + End If + Next initConfl + + 'Export data to Excel + Dim objExcel As Microsoft.Office.Interop.Excel.Application + objExcel = CreateObject("Excel.Application") + objExcel.Visible = True + objExcel.Workbooks.Add() + objExcel.ActiveWorkbook.Sheets.Add.Name = "Precedence Matrix" + Dim objSheet1, objSheet2 As Object + objSheet1 = objExcel.ActiveWorkbook.Worksheets(2) + objSheet1.Name = "Assembly Directions" + objSheet2 = objExcel.ActiveWorkbook.Worksheets(1) + + 'Assembly directions + objSheet1.Cells(1, 1).Value = "Product" + objSheet1.Cells(1, 2).Value = "+X" + objSheet1.Cells(1, 3).Value = "+Y" + objSheet1.Cells(1, 4).Value = "+Z" + objSheet1.Cells(1, 5).Value = "-X" + objSheet1.Cells(1, 6).Value = "-Y" + objSheet1.Cells(1, 7).Value = "-Z" + objSheet1.Cells(1, 8).Value = "Assembly Tier" + For int_i = 0 To cRelevantProducts.Count - 1 + objSheet1.Cells(int_i + 2, 1).Value = cRelevantProducts.Item(int_i).Name + For intAxis = 0 To intJ - 1 + objSheet1.Cells(int_i + 2, 2 + intAxis).Value = disassDir(int_i, intAxis) + Next intAxis + objSheet1.Cells(int_i + 2, intJ + 2).Value = aTiers(int_i) + Next int_i + + 'Precedence relations + For int_i = 0 To cRelevantProducts.Count - 1 + For int_j = 0 To cRelevantProducts.Count - 1 + objSheet2.Cells(int_i + 1, int_j + 1).Value = precedenceMatrix(int_i, int_j) + Next int_j + Next int_i + + 'Save and close excel workbook + If bConnectivityCheck Then + objExcel.ActiveWorkbook.SaveAs(Filename:=xlsPath & xlsFileName & "_AssemblyTiers_CC.xlsx") + Else + objExcel.ActiveWorkbook.SaveAs(Filename:=xlsPath & xlsFileName & "_AssemblyTiers.xlsx") + End If + objExcel.ActiveWorkbook.Close(SaveChanges:=True) + 'close the excel application + objExcel.Quit() + ReleaseObject(objExcel) + + End Sub + Sub ExtractProducts(oCurrentProduct As Product) + + Dim oCurrentTreeNode As Product + Dim i As Integer + + For i = 1 To oCurrentProduct.Products.Count + oCurrentTreeNode = oCurrentProduct.Products.Item(i) + + 'recursive + If oCurrentTreeNode.Products.Count > 0 Then + ExtractProducts(oCurrentTreeNode) + Else + Debug.Print(oCurrentTreeNode.PartNumber & " (" & oCurrentTreeNode.Name & ") is a leaf product") + 'remove special characters from the part number + Dim newPartNo As String + Dim newCharacter As String + newCharacter = " " + newPartNo = oCurrentTreeNode.PartNumber + newPartNo = Replace(newPartNo, "<", newCharacter) + newPartNo = Replace(newPartNo, ">", newCharacter) + newPartNo = Replace(newPartNo, "/", newCharacter) + oCurrentTreeNode.PartNumber = newPartNo + cAllProducts.Add(oCurrentTreeNode) + End If + + Next + + End Sub + + Sub GetNextNode(oCurrentProduct As Product) + + Dim oCurrentTreeNode As Product + Dim i As Integer + + For i = 1 To oCurrentProduct.Products.Count + oCurrentTreeNode = oCurrentProduct.Products.Item(i) + + If IsPart(oCurrentTreeNode) = True Then + MsgBox(oCurrentTreeNode.PartNumber & " is a part") + ElseIf IsProduct(oCurrentTreeNode) = True Then + MsgBox(oCurrentTreeNode.PartNumber & " is a product") + Else + MsgBox(oCurrentTreeNode.PartNumber & " is a component") + End If + + 'recursive + If oCurrentTreeNode.Products.Count > 0 Then + GetNextNode(oCurrentTreeNode) + End If + + Next + + End Sub + + Function IsPart(objCurrentProduct As Product) As Boolean + + Dim oTestPart As PartDocument + + oTestPart = Nothing + + On Error Resume Next + + oTestPart = CATIA.Documents.Item(objCurrentProduct.PartNumber & ".CATPart") + + If Not oTestPart Is Nothing Then + IsPart = True + Else + IsPart = False + End If + + End Function + + Function IsProduct(objCurrentProduct As Product) As Boolean + + Dim oTestProduct As ProductDocument + + oTestProduct = Nothing + + On Error Resume Next + + oTestProduct = CATIA.Documents.Item(objCurrentProduct.PartNumber & ".CATProduct") + + If Not oTestProduct Is Nothing Then + IsProduct = True + Else + IsProduct = False + End If + + End Function + Sub Liaison() + + Dim n As Integer = cRelevantProducts.Count + + ReDim liaisonMatrix(n - 1, n - 1) + + 'access the clash technology object + Dim cClashes As Clashes + cClashes = CATIA.ActiveDocument.Product.GetTechnologicalObject("Clashes") + 'access the groups technology object + Dim cGroups As Groups + cGroups = CATIA.ActiveDocument.Product.GetTechnologicalObject("Groups") + + 'Clash analysis between all products (clash type = contact) + Dim int_i, int_j As Integer + For int_i = 1 To cRelevantProducts.Count + For int_j = 1 To cRelevantProducts.Count + If int_j > int_i Then 'only need one half of the combinations + Dim group1 As Group + Dim group2 As Group + group1 = cGroups.Add + group2 = cGroups.Add + group1.AddExplicit(cRelevantProducts.Item(int_i - 1)) + group2.AddExplicit(cRelevantProducts.Item(int_j - 1)) + 'create a new clash analysis + Dim oClash As Clash + oClash = cClashes.Add + oClash.ComputationType = CatClashComputationType.catClashComputationTypeBetweenTwo + oClash.FirstGroup = group1 + oClash.SecondGroup = group2 + oClash.InterferenceType = CatClashInterferenceType.catClashInterferenceTypeContact + oClash.Compute() + Dim cConflicts As Conflicts + cConflicts = oClash.Conflicts + If cConflicts.Count > 0 Then + 'For each contact, write 1 in the spreadsheet + 'The matrix is symmetric and 0-diagonal + liaisonMatrix(int_i - 1, int_j - 1) = 1 + liaisonMatrix(int_j - 1, int_i - 1) = 1 + Else + liaisonMatrix(int_i - 1, int_j - 1) = 0 + liaisonMatrix(int_j - 1, int_i - 1) = 0 + End If + ElseIf int_j = int_i Then + liaisonMatrix(int_i - 1, int_j - 1) = 0 + End If + Next int_j + Next int_i + + End Sub + + Function SubassemblyIsConnected(prt As List(Of Integer)) As Boolean + + 'List of visited nodes + Dim visitedNodes As New List(Of Boolean) + Dim prtCount As Integer = prt.Count + For x = 0 To prtCount - 1 + visitedNodes.Add(False) + Next + + 'Submatrix of liaison adjacency matrix that contains only the nodes of this subassembly + Dim liaisonSubmatrix(,) As Integer + ReDim liaisonSubmatrix(prtCount, prtCount) + For m = 0 To prtCount - 1 + For k = 0 To prtCount - 1 + liaisonSubmatrix(m, k) = liaisonMatrix(prt(m), prt(k)) + Next + Next + + 'Depth-first search to explore the liaison subgraph from the first node + DFS(liaisonSubmatrix, visitedNodes, 0) + + 'Check whether all nodes could be visited via liaison connections + For i = 0 To prtCount - 1 + If visitedNodes(i) = False Then + Return False + End If + Next + + Return True + + End Function + + Sub DFS(liaisonSubmatrix(,) As Integer, visitedNodes As List(Of Boolean), v As Integer) + 'Depth-first search + + If visitedNodes(v) = True Then + Exit Sub + End If + + visitedNodes(v) = True + + 'Neighbors of v + Dim neighbors As New List(Of Integer) + For i = 0 To visitedNodes.Count - 1 + If liaisonSubmatrix(v, i) = 1 Then + neighbors.Add(i) + End If + Next + + 'Do DFS on all neighbor nodes if they were not visited + For Each u In neighbors + If visitedNodes(u) = False Then + DFS(liaisonSubmatrix, visitedNodes, u) + End If + Next + + End Sub + Function DeactivateFasteners(objProduct As Product) + + Dim objParts As New ArrayList + 'On the top level of product tree + ' objParts = objProduct.Products + 'Recursive + objParts = cAllProducts + Dim selection1 As Selection + selection1 = CATIA.ActiveDocument.Selection + selection1.Clear() + + Dim intFasteners As Integer + intFasteners = 0 + + For Each prod In objParts + Dim sName As String + Dim primFastSize As Integer + + sName = LCase(prod.PartNumber) + 'Debug.Print sName + If InStr(sName, "bolt") > 0 Then + Debug.Print(prod.Name + " was identified as a bolt") + selection1.Add(prod) + + primaryFasteners.Add(prod) + + CATIA.StartCommand("Activate / Deactivate Component") + selection1.Clear() + intFasteners = intFasteners + 1 + ElseIf InStr(sName, "screw") > 0 Or InStr(sName, "schraube") > 0 Or (InStr(sName, "iso") > 0 And InStr(sName, "4762") > 0) Or (InStr(sName, "din") > 0 And (InStr(sName, "912") > 0 Or InStr(sName, "933") > 0)) Then + Debug.Print(prod.Name + " was identified as a screw") + selection1.Add(prod) + + primaryFasteners.Add(prod) + + CATIA.StartCommand("Activate / Deactivate Component") + selection1.Clear() + intFasteners = intFasteners + 1 + ElseIf InStr(sName, "clip") > 0 Then + Debug.Print(prod.Name + " was identified as a clip") + selection1.Add(prod) + + primaryFasteners.Add(prod) + + CATIA.StartCommand("Activate / Deactivate Component") + selection1.Clear() + intFasteners = intFasteners + 1 + ElseIf InStr(sName, "wedge") > 0 Then + Debug.Print(prod.Name + " was identified as a wedge") + selection1.Add(prod) + + primaryFasteners.Add(prod) + + CATIA.StartCommand("Activate / Deactivate Component") + selection1.Clear() + intFasteners = intFasteners + 1 + 'ElseIf InStr(sName, "pin") > 0 Then + ' Debug.Print(prod.Name + " was identified as a pin") + ' selection1.Add(prod) + + ' primaryFasteners.Add(prod) + + ' CATIA.StartCommand("Activate / Deactivate Component") + ' selection1.Clear() + ' intFasteners = intFasteners + 1 + ElseIf InStr(sName, "nut") > 0 Or (InStr(sName, "iso") > 0 And InStr(sName, "4161") > 0) Or (InStr(sName, "din") > 0 And (InStr(sName, "934") > 0 Or InStr(sName, "439") > 0)) Then + Debug.Print(prod.Name + " was identified as a nut") + selection1.Add(prod) + + secondaryFasteners.Add(prod) + + CATIA.StartCommand("Activate / Deactivate Component") + selection1.Clear() + intFasteners = intFasteners + 1 + ElseIf InStr(sName, "washer") > 0 Or (InStr(sName, "din") > 0 And (InStr(sName, "9021") > 0 Or InStr(sName, "125") > 0 Or InStr(sName, "127") > 0)) Then + Debug.Print(prod.Name + " was identified as a washer") + selection1.Add(prod) + + secondaryFasteners.Add(prod) + + CATIA.StartCommand("Activate / Deactivate Component") + selection1.Clear() + intFasteners = intFasteners + 1 + Else + cRelevantProducts.Add(prod) + End If + Next + + 'CATIA.StartCommand ("Activate / Deactivate Component") + Debug.Print("Deactivated " + CStr(intFasteners) + " fasteners") + intParts = intParts - intFasteners + Debug.Print(CStr(intParts) + " parts to assemble") + MsgBox("Fasteners are deacivated. Press OK to proceed.") + + End Function + + Function GenerateBoundingBox(partDocument1 As PartDocument, objProduct As Product, i As Integer) + 'Processes a single part to extract its origin XYZ, min/max X/Y/Z + + CATIA.DisplayFileAlerts = False + + 'Declare variables + Dim axis + Dim remake + Dim part1 As Part + Dim axisref As Object + Dim shapeFactory1 As ShapeFactory + Dim hybridShapeFactory1 As HybridShapeFactory + Dim sStatus As String + Dim hybridShapeD1, hybridShapeD2, hybridShapeD3 As HybridShapeDirection + Dim a1, a2, a3, a4, a5, a6 'To change the offsets of the box + Dim bodies1 As Bodies + Dim body1 As Body + Dim reference1 As Reference + Dim HybridShapeExtremum1, HybridShapeExtremum2, HybridShapeExtremum3 As HybridShapeExtremum + Dim HybridShapeExtremum4, HybridShapeExtremum5, HybridShapeExtremum6 As HybridShapeExtremum + Dim originCoord(2) + Dim faceSel As Object + + 'Check whether we are processing a Part + If (InStr(partDocument1.Name, ".CATPart")) <> 0 Then + part1 = partDocument1.Part + hybridShapeFactory1 = part1.HybridShapeFactory + + Dim axiscoord(2) + Dim axissyst + + Dim axisSystem As AxisSystem + axisSystem = part1.AxisSystems.Item(1) + + axissyst = axisSystem + axisref = axisSystem + + Dim ref_name_systaxis As String + ref_name_systaxis = axissyst.Name + + axissyst.IsCurrent = 1 + axissyst.Name = "BBoxAxis" + Dim axname As String + axname = axissyst.Name + + 'Get Product's Position (rotation and translation) + '(for now: relative to the parent product!) + Dim PositionArray(11) + Dim oPosition As Object + oPosition = objProduct.Position + oPosition.GetComponents(PositionArray) + + Dim originpoint As HybridShapePointCoord + axissyst.GetOrigin(originCoord) + 'MsgBox "X0 = " & CStr(originCoord(0)) & vbNewLine & "Y0 = " & CStr(originCoord(1)) & vbNewLine & "Z0 = " & CStr(originCoord(2)) + + originpoint = hybridShapeFactory1.AddNewPointCoord(originCoord(0), originCoord(1), originCoord(2)) + axisref = part1.CreateReferenceFromObject(originpoint) + axissyst.GetXAxis(axiscoord) + hybridShapeD1 = hybridShapeFactory1.AddNewDirectionByCoord(axiscoord(0), axiscoord(1), axiscoord(2)) + axissyst.GetYAxis(axiscoord) + hybridShapeD2 = hybridShapeFactory1.AddNewDirectionByCoord(axiscoord(0), axiscoord(1), axiscoord(2)) + axissyst.GetZAxis(axiscoord) + hybridShapeD3 = hybridShapeFactory1.AddNewDirectionByCoord(axiscoord(0), axiscoord(1), axiscoord(2)) + + 'hybridShapeD1&2 are not set yet, but used for line creation (from origin of the axis system) + Dim Plane_line_1 As HybridShapeLinePtDir + Plane_line_1 = hybridShapeFactory1.AddNewLinePtDir(originpoint, hybridShapeD1, 0, 0, False) + Dim Plane_line_2 As HybridShapeLinePtDir + Plane_line_2 = hybridShapeFactory1.AddNewLinePtDir(originpoint, hybridShapeD2, 0, 0, False) + + Dim oBodies As Bodies + oBodies = part1.Bodies + + 'J is defined to make unique names for Axis and the Body for the bounding box + Dim j As Integer + j = oBodies.Count + + 'Add new Body "Bounding Box."j to the Bodies of the current Part + bodies1 = part1.Bodies + body1 = bodies1.Add() + body1.Name = "Bounding Box." & j + + Dim hybridBodies1 As HybridBodies + hybridBodies1 = body1.HybridBodies + Dim hybridBody1 As HybridBody + hybridBody1 = hybridBodies1.Add + hybridBody1.Name = "definition_points" + + + 'Pick a face of the part to use for HybridShapeExtract + faceSel = CATIA.ActiveDocument.Selection + faceSel.Clear + 'The current Part is added to the selection + faceSel.Add(part1) + 'The selection gets rewritten by all the Faces of the selected part ("sel") + faceSel.Search("Type=Face,sel") + + Debug.Print("Selected faces: " & CStr(faceSel.Count)) + intNumFaces += faceSel.Count + + 'Need to check whether Extract crashes given this face and try the next one + Dim f As Integer + For f = 1 To faceSel.Count + + 'On Error GoTo ContinueFaceLoop + + reference1 = faceSel.Item(f).Value + Debug.Print(TypeName(reference1)) + + Dim hybridShapeExtract1 As HybridShapeExtract + hybridShapeExtract1 = hybridShapeFactory1.AddNewExtract(reference1) + hybridShapeExtract1.PropagationType = 1 'point continuity + hybridShapeExtract1.ComplementaryExtract = False + hybridShapeExtract1.IsFederated = False + reference1 = hybridShapeExtract1 + + 'Create the 6 Extrenum items for the Solid/Surf. May not be single points, will be solved with next points + HybridShapeExtremum1 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD1, 1) + HybridShapeExtremum2 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD1, 0) + HybridShapeExtremum3 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD2, 1) + HybridShapeExtremum4 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD2, 0) + HybridShapeExtremum5 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD3, 1) + HybridShapeExtremum6 = hybridShapeFactory1.AddNewExtremum(reference1, hybridShapeD3, 0) + + ' Creates Geometrical Set under the Solid, to contain the construction elements + + Dim hybridBody2 As HybridBody + hybridBody2 = hybridBodies1.Item("definition_points") + + hybridBody2.AppendHybridShape(HybridShapeExtremum1) + part1.InWorkObject = HybridShapeExtremum1 + HybridShapeExtremum1.Name = "max_X" + hybridBody2.AppendHybridShape(HybridShapeExtremum2) + part1.InWorkObject = HybridShapeExtremum2 + HybridShapeExtremum2.Name = "min_X" + hybridBody2.AppendHybridShape(HybridShapeExtremum3) + part1.InWorkObject = HybridShapeExtremum3 + HybridShapeExtremum3.Name = "max_Y" + hybridBody2.AppendHybridShape(HybridShapeExtremum4) + part1.InWorkObject = HybridShapeExtremum4 + HybridShapeExtremum4.Name = "min_Y" + hybridBody2.AppendHybridShape(HybridShapeExtremum5) + part1.InWorkObject = HybridShapeExtremum5 + HybridShapeExtremum5.Name = "max_Z" + hybridBody2.AppendHybridShape(HybridShapeExtremum6) + part1.InWorkObject = HybridShapeExtremum6 + HybridShapeExtremum6.Name = "min_Z" + + part1.UpdateObject(HybridShapeExtremum1) + part1.UpdateObject(HybridShapeExtremum2) + part1.UpdateObject(HybridShapeExtremum3) + part1.UpdateObject(HybridShapeExtremum4) + part1.UpdateObject(HybridShapeExtremum5) + part1.UpdateObject(HybridShapeExtremum6) + + 'part1.Update + + ' Creates a 6 single points using the Extrenums as refs, so if the Extrenum was a line or surf, you can still off planes to these points + + Dim Ref1 As Reference + Ref1 = part1.CreateReferenceFromObject(HybridShapeExtremum1) + Dim Point1 As HybridShapePointCoord + Point1 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref1) + hybridBody2.AppendHybridShape(Point1) + Dim point_ref11 As Reference + point_ref11 = part1.CreateReferenceFromObject(Point1) + + Dim Ref2 As Reference + Ref2 = part1.CreateReferenceFromObject(HybridShapeExtremum2) + Dim Point2 As HybridShapePointCoord + Point2 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref2) + hybridBody2.AppendHybridShape(Point2) + Dim point_ref12 As Reference + point_ref12 = part1.CreateReferenceFromObject(Point2) + + Dim Ref3 As Reference + Ref3 = part1.CreateReferenceFromObject(HybridShapeExtremum3) + Dim Point3 As HybridShapePointCoord + Point3 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref3) + hybridBody2.AppendHybridShape(Point3) + Dim point_ref13 As Reference + point_ref13 = part1.CreateReferenceFromObject(Point3) + + Dim Ref4 As Reference + Ref4 = part1.CreateReferenceFromObject(HybridShapeExtremum4) + Dim Point4 As HybridShapePointCoord + Point4 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref4) + hybridBody2.AppendHybridShape(Point4) + Dim point_ref14 As Reference + point_ref14 = part1.CreateReferenceFromObject(Point4) + + Dim Ref5 As Reference + Ref5 = part1.CreateReferenceFromObject(HybridShapeExtremum5) + Dim Point5 As HybridShapePointCoord + Point5 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref5) + hybridBody2.AppendHybridShape(Point5) + Dim point_ref5 As Reference + point_ref5 = part1.CreateReferenceFromObject(Point5) + + Dim Ref6 As Reference + Ref6 = part1.CreateReferenceFromObject(HybridShapeExtremum6) + Dim Point6 As HybridShapePointCoord + Point6 = hybridShapeFactory1.AddNewPointCoordWithReference(0, 0, 0, Ref6) + hybridBody2.AppendHybridShape(Point6) + Dim point_ref6 As Reference + point_ref6 = part1.CreateReferenceFromObject(Point6) + + part1.UpdateObject(Point1) + part1.UpdateObject(Point2) + part1.UpdateObject(Point3) + part1.UpdateObject(Point4) + part1.UpdateObject(Point5) + part1.UpdateObject(Point6) + + 'part1.Update + + axissyst.IsCurrent = 1 + + 'Read extremum coordinates + Dim coord(2) As Object + Dim absCoord(2) As Object + + Dim TheSPAWorkbench As Workbench + TheSPAWorkbench = CATIA.ActiveDocument.GetWorkbench("SPAWorkbench") + + Dim TheMeasurable + + Debug.Print("Global coordinates of local extrema:") + + 'Transform local extrema coordinates into global coordinates and update aAssemblyBoundaries + + 'Distances to Part Bounding Box faces in local coordinates + Dim aBBDistances(5) As Double + '8 corner points of the Part Bounding Box (BB) in local coordinates (8x3 array) + Dim aBBCornersLocal(7, 2) As Double + + 'max_X_loc + TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref11) + TheMeasurable.GetPoint(coord) + aBBDistances(0) = coord(0) + absCoord = {0.0, 0.0, 0.0} + Call Coord_Transform(coord, absCoord, objProduct, True) + Debug.Print(Point1.Name & " (" & Ref1.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]") + + 'min_X_loc + TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref12) + TheMeasurable.GetPoint(coord) + aBBDistances(1) = coord(0) + absCoord = {0.0, 0.0, 0.0} + Call Coord_Transform(coord, absCoord, objProduct, True) + Debug.Print(Point2.Name & " (" & Ref2.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]") + + 'max_Y_loc + TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref13) + TheMeasurable.GetPoint(coord) + aBBDistances(2) = coord(1) + absCoord = {0.0, 0.0, 0.0} + Call Coord_Transform(coord, absCoord, objProduct, True) + Debug.Print(Point3.Name & " (" & Ref3.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]") + + 'min_Y_loc + TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref14) + TheMeasurable.GetPoint(coord) + aBBDistances(3) = coord(1) + absCoord = {0.0, 0.0, 0.0} + Call Coord_Transform(coord, absCoord, objProduct, True) + Debug.Print(Point4.Name & " (" & Ref4.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]") + + 'max_Z_loc + TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref5) + TheMeasurable.GetPoint(coord) + aBBDistances(4) = coord(2) + absCoord = {0.0, 0.0, 0.0} + Call Coord_Transform(coord, absCoord, objProduct, True) + Debug.Print(Point5.Name & " (" & Ref5.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]") + + 'min_Z_loc + TheMeasurable = TheSPAWorkbench.GetMeasurable(point_ref6) + TheMeasurable.GetPoint(coord) + aBBDistances(5) = coord(2) + absCoord = {0.0, 0.0, 0.0} + Call Coord_Transform(coord, absCoord, objProduct, True) + Debug.Print(Point6.Name & " (" & Ref6.DisplayName & "): [" & absCoord(0) & " " & absCoord(1) & " " & absCoord(2) & "]") + + 'Generate 8 corner points (local coordinates) to the aBBCornersLocal + Dim m, n, k, c As Integer + c = 0 + For m = 0 To 1 + For n = 2 To 3 + For k = 4 To 5 + aBBCornersLocal(c, 0) = aBBDistances(m) + aBBCornersLocal(c, 1) = aBBDistances(n) + aBBCornersLocal(c, 2) = aBBDistances(k) + 'Transform corner point into global coordinates + coord(0) = aBBCornersLocal(c, 0) + coord(1) = aBBCornersLocal(c, 1) + coord(2) = aBBCornersLocal(c, 2) + Call Coord_Transform(coord, absCoord, objProduct, True) + 'Record values to aPartBBGlob + Dim CCC(2) As Double 'Corner Coordinates in axis system Congruent to global but in the part's origin + CCC(0) = absCoord(0) - PositionArray(9) + CCC(1) = absCoord(1) - PositionArray(10) + CCC(2) = absCoord(2) - PositionArray(11) + If CCC(0) > aPartBBGlob(i, 0) Then + aPartBBGlob(i, 0) = CCC(0) + End If + If CCC(0) < aPartBBGlob(i, 1) Then + aPartBBGlob(i, 1) = CCC(0) + End If + If CCC(1) > aPartBBGlob(i, 2) Then + aPartBBGlob(i, 2) = CCC(1) + End If + If CCC(1) < aPartBBGlob(i, 3) Then + aPartBBGlob(i, 3) = CCC(1) + End If + If CCC(2) > aPartBBGlob(i, 4) Then + aPartBBGlob(i, 4) = CCC(2) + End If + If CCC(2) < aPartBBGlob(i, 5) Then + aPartBBGlob(i, 5) = CCC(2) + End If + 'Update aAssemblyBoundaries (global) + If absCoord(0) > aAssemblyBoundaries(0) Then + aAssemblyBoundaries(0) = absCoord(0) + End If + If absCoord(0) < aAssemblyBoundaries(1) Then + aAssemblyBoundaries(1) = absCoord(0) + End If + If absCoord(1) > aAssemblyBoundaries(2) Then + aAssemblyBoundaries(2) = absCoord(1) + End If + If absCoord(1) < aAssemblyBoundaries(3) Then + aAssemblyBoundaries(3) = absCoord(1) + End If + If absCoord(2) > aAssemblyBoundaries(4) Then + aAssemblyBoundaries(4) = absCoord(2) + End If + If absCoord(2) < aAssemblyBoundaries(5) Then + aAssemblyBoundaries(5) = absCoord(2) + End If + c = c + 1 + Next k + Next n + Next m + + part1.Update() + + Exit For + + 'ContinueFaceLoop: + + Next f + + Else + MsgBox("The active document must be a CATPart") + End If + + End Function + + Sub RecalculateRemovalDistances(cRelProd As ArrayList, bDeact As Boolean()) + + Dim aRemovalDistances(cRelProd.Count - 1, 5) + Dim i As Integer + Dim relProd As Product + 'assure that the origin is inside the BB of assembly + aAssemblyBoundaries(0) = -1 / 0 + aAssemblyBoundaries(1) = 1 / 0 + aAssemblyBoundaries(2) = -1 / 0 + aAssemblyBoundaries(3) = 1 / 0 + aAssemblyBoundaries(4) = -1 / 0 + aAssemblyBoundaries(5) = 1 / 0 + + For i = 0 To cRelProd.Count - 1 + If Not bDeact(i) Then + If aInitPos(i, 9) + aPartBBGlob(i, 0) > aAssemblyBoundaries(0) Then + aAssemblyBoundaries(0) = aInitPos(i, 9) + aPartBBGlob(i, 0) + End If + If aInitPos(i, 9) + aPartBBGlob(i, 1) < aAssemblyBoundaries(1) Then + aAssemblyBoundaries(1) = aInitPos(i, 9) + aPartBBGlob(i, 1) + End If + If aInitPos(i, 10) + aPartBBGlob(i, 2) > aAssemblyBoundaries(2) Then + aAssemblyBoundaries(2) = aInitPos(i, 10) + aPartBBGlob(i, 2) + End If + If aInitPos(i, 10) + aPartBBGlob(i, 3) < aAssemblyBoundaries(3) Then + aAssemblyBoundaries(3) = aInitPos(i, 10) + aPartBBGlob(i, 3) + End If + If aInitPos(i, 11) + aPartBBGlob(i, 4) > aAssemblyBoundaries(4) Then + aAssemblyBoundaries(4) = aInitPos(i, 11) + aPartBBGlob(i, 4) + End If + If aInitPos(i, 11) + aPartBBGlob(i, 5) < aAssemblyBoundaries(5) Then + aAssemblyBoundaries(5) = aInitPos(i, 11) + aPartBBGlob(i, 5) + End If + End If + Next i + + For i = 0 To cRelProd.Count - 1 + If Not bDeact(i) Then + aRemovalDistances(i, 0) = aAssemblyBoundaries(0) - aPartBBGlob(i, 1) + aRemovalDistances(i, 1) = aAssemblyBoundaries(1) - aPartBBGlob(i, 0) + aRemovalDistances(i, 2) = aAssemblyBoundaries(2) - aPartBBGlob(i, 3) + aRemovalDistances(i, 3) = aAssemblyBoundaries(3) - aPartBBGlob(i, 2) + aRemovalDistances(i, 4) = aAssemblyBoundaries(4) - aPartBBGlob(i, 5) + aRemovalDistances(i, 5) = aAssemblyBoundaries(5) - aPartBBGlob(i, 4) + End If + Next i + + End Sub + + 'Public Function ArrayLen(a As Object) As Integer + ' If IsEmpty(a) Then + ' ArrayLen = 0 + ' Else + ' ArrayLen = UBound(a) - LBound(a) + 1 + ' End If + 'End Function + + Function Det3x3(dX11 As Double, dX12 As Double, dX13 As Double, + dX21 As Double, dX22 As Double, dX23 As Double, + dX31 As Double, dX32 As Double, dX33 As Double) As Double + '*********************************************** + '* + '* 3x3 matrix determinant calculation (direct) + '* + '*********************************************** + + Det3x3 = dX11 * dX22 * dX33 + dX12 * dX23 * dX31 + dX21 * dX32 * dX13 - + dX13 * dX22 * dX31 - dX12 * dX21 * dX33 - dX23 * dX32 * dX11 + End Function + Function Inv3x3(dX11 As Double, dX12 As Double, dX13 As Double, + dX21 As Double, dX22 As Double, dX23 As Double, + dX31 As Double, dX32 As Double, dX33 As Double, aInv() As Double) As Double() + '*********************************************** + '* + '* 3x3 matrix inverse calculation (direct) + '* + '*********************************************** + Dim dDet As Double + + ReDim aInv(8) + + dDet = Det3x3(dX11, dX12, dX13, dX21, dX22, dX23, dX31, dX32, dX33) + 'If dDet = 0 Then Exit Function + If dDet = 0 Then Return Nothing + + aInv(0) = (dX22 * dX33 - dX23 * dX32) / Math.Abs(dDet) + aInv(1) = (dX13 * dX32 - dX12 * dX33) / Math.Abs(dDet) + aInv(2) = (dX12 * dX23 - dX13 * dX22) / Math.Abs(dDet) + aInv(3) = (dX23 * dX31 - dX21 * dX33) / Math.Abs(dDet) + aInv(4) = (dX11 * dX33 - dX13 * dX31) / Math.Abs(dDet) + aInv(5) = (dX13 * dX21 - dX11 * dX23) / Math.Abs(dDet) + aInv(6) = (dX21 * dX32 - dX22 * dX31) / Math.Abs(dDet) + aInv(7) = (dX12 * dX31 - dX11 * dX32) / Math.Abs(dDet) + aInv(8) = (dX11 * dX22 - dX12 * dX21) / Math.Abs(dDet) + + Return aInv + + End Function + Sub Coord_Transform(aRel() As Object, aAbs() As Object, oProduct As Product, bRecursively As Boolean) + + Dim vProduct As Object, vCoord(11) + Dim oFatherProduct As Product + Dim aInv(8) As Double + + 'Exit condition, empty object + If oProduct Is Nothing Then Exit Sub + + 'Redim absolute coords matrix + On Error Resume Next + 'aAbs = {0.0, 0.0, 0.0} + On Error GoTo 0 + + 'Calculate product coordinates + vProduct = oProduct + vProduct.Position.GetComponents(vCoord) + + 'Calculate inverse matrix + If IsNothing(Inv3x3(CDbl(vCoord(0)), CDbl(vCoord(1)), CDbl(vCoord(2)), + CDbl(vCoord(3)), CDbl(vCoord(4)), CDbl(vCoord(5)), + CDbl(vCoord(6)), CDbl(vCoord(7)), CDbl(vCoord(8)), aInv)) Then + 'MsgBox "Error, degenerate transformation", vbOKOnly + Exit Sub + Else + aInv = Inv3x3(CDbl(vCoord(0)), CDbl(vCoord(1)), CDbl(vCoord(2)), + CDbl(vCoord(3)), CDbl(vCoord(4)), CDbl(vCoord(5)), + CDbl(vCoord(6)), CDbl(vCoord(7)), CDbl(vCoord(8)), aInv) + End If + + 'Calculate transformation + aAbs(0) = vCoord(9) + aInv(0) * aRel(0) + aInv(1) * aRel(1) + aInv(2) * aRel(2) + aAbs(1) = vCoord(10) + aInv(3) * aRel(0) + aInv(4) * aRel(1) + aInv(5) * aRel(2) + aAbs(2) = vCoord(11) + aInv(6) * aRel(0) + aInv(7) * aRel(1) + aInv(8) * aRel(2) + + 'If recursive option sepecified, search for parents and applies the transformation again + If bRecursively Then + + 'Try to assign parent + oFatherProduct = Nothing + On Error Resume Next + oFatherProduct = oProduct.Parent.Parent + On Error GoTo 0 + + 'If OK, recalculate coords + If oFatherProduct Is Nothing Then + Else + If oFatherProduct.PartNumber + ".CATProduct" = CATIA.ActiveDocument.Name Then + aRel(0) = aAbs(0) + aRel(1) = aAbs(1) + aRel(2) = aAbs(2) + Coord_Transform(aRel, aAbs, oFatherProduct, False) + Else + aRel(0) = aAbs(0) + aRel(1) = aAbs(1) + aRel(2) = aAbs(2) + Coord_Transform(aRel, aAbs, oFatherProduct, True) + End If + End If + + End If + + End Sub + + Function productIsInCollection(objProd As Product, prodColl As ArrayList) As Boolean + Dim dummyObj As Product + productIsInCollection = False + For Each dummyObj In prodColl + If dummyObj.Name = objProd.Name Then + productIsInCollection = True + Exit For + End If + Next + End Function + + Sub moveProduct(objProd As Product, intDir As Integer, bPositive As Boolean) + Dim intS As Integer + If bPositive = True Then + intS = intStep + Else + intS = -intStep + End If + Dim moveArray(11) + moveArray(0) = 1 + moveArray(1) = 0 + moveArray(2) = 0 + moveArray(3) = 0 + moveArray(4) = 1 + moveArray(5) = 0 + moveArray(6) = 0 + moveArray(7) = 0 + moveArray(8) = 1 + moveArray(9) = 0 + moveArray(10) = 0 + moveArray(11) = 0 + + Dim axisArray(11) + + 'movement along global axis + If intDir < 6 Then + 'Attention: for now it is assumed that all products are on the top level of specification tree + If intDir = 0 Then + moveArray(9) = intS + End If + If intDir = 1 Then + moveArray(10) = intS + End If + If intDir = 2 Then + moveArray(11) = intS + End If + If intDir = 3 Then + moveArray(9) = -intS + End If + If intDir = 4 Then + moveArray(10) = -intS + End If + If intDir = 5 Then + moveArray(11) = -intS + End If + Else 'movement along local axis + Dim oPosition As Object + oPosition = objProd.Position + oPosition.GetComponents(axisArray) + If intDir = 6 Then + moveArray(9) = axisArray(0) * intS + moveArray(10) = axisArray(1) * intS + moveArray(11) = axisArray(2) * intS + End If + If intDir = 7 Then + moveArray(9) = axisArray(3) * intS + moveArray(10) = axisArray(4) * intS + moveArray(11) = axisArray(5) * intS + End If + If intDir = 8 Then + moveArray(9) = axisArray(6) * intS + moveArray(10) = axisArray(7) * intS + moveArray(11) = axisArray(8) * intS + End If + If intDir = 9 Then + moveArray(9) = -axisArray(0) * intS + moveArray(10) = -axisArray(1) * intS + moveArray(11) = -axisArray(2) * intS + End If + If intDir = 10 Then + moveArray(9) = -axisArray(3) * intS + moveArray(10) = -axisArray(4) * intS + moveArray(11) = -axisArray(5) * intS + End If + If intDir = 11 Then + moveArray(9) = -axisArray(6) * intS + moveArray(10) = -axisArray(7) * intS + moveArray(11) = -axisArray(8) * intS + End If + End If + Dim prod1nd As Product + prod1nd = objProd + prod1nd.Move.Apply(moveArray) + + End Sub + + Function collisionDetected(cClashes As Clashes, group1 As Group, group2 As Group) As Boolean + 'cRelevantProducts As Collection, cDeactivated As Collection + + collisionDetected = False + + 'define two groups + ' Dim group1 As Group + 'Dim group2 As Group + ' group1 = cGroups.Add + ' group2 = cGroups.Add + ' group1.AddExplicit product1 + ' Dim relevantProduct As Product + ' For Each relevantProduct In cRelevantProducts + ' If Not relevantProduct.Name = product1.Name And Not productIsInCollection(relevantProduct, cDeactivated) Then + ' group2.AddExplicit relevantProduct + ' End If + ' Next relevantProduct + 'create a new clash analysis + Dim oClash As Clash + oClash = cClashes.Add + oClash.ComputationType = SPATypeLib.CatClashComputationType.catClashComputationTypeBetweenTwo + oClash.FirstGroup = group1 + oClash.SecondGroup = group2 + oClash.InterferenceType = SPATypeLib.CatClashInterferenceType.catClashInterferenceTypeClearance + 'oClash.Clearance = dCollSens + oClash.Compute() + Dim cConflicts As Conflicts + cConflicts = oClash.Conflicts + If cConflicts.Count > 0 Then + 'MsgBox "Detected a collision: " & product1.Name + 'If at least one conflict value exceeds the collision sensitivity, it is a collision + Dim oConflict As Conflict + Dim c As Integer + For c = 1 To cConflicts.Count + oConflict = cConflicts.Item(c) + oConflict.Status = SPATypeLib.CatConflictStatus.catConflictStatusRelevant + If oConflict.Type = SPATypeLib.CatConflictType.catConflictTypeClash Then + If oConflict.Value < -dCollSens Then + collisionDetected = True + 'Debug.Print("Clash detected: " & oConflict.FirstProduct.Name & " - " & oConflict.SecondProduct.Name & " = " & oConflict.Value) + Exit For + End If + End If + Next c + End If + End Function + + Function productReachedFinalPosition(objProd As Product, i1 As Integer) As Boolean + productReachedFinalPosition = False + Dim posArray(11) + Dim oPosition As Object + oPosition = objProd.Position + oPosition.GetComponents(posArray) + If posArray(9) > aRemovalDistances(i1, 0) Then + productReachedFinalPosition = True + 'MsgBox "X+ removal distance reached by " & objProd.Name + End If + If posArray(9) < aRemovalDistances(i1, 1) Then + productReachedFinalPosition = True + 'MsgBox "X- removal distance reached by " & objProd.Name + End If + If posArray(10) > aRemovalDistances(i1, 2) Then + productReachedFinalPosition = True + 'MsgBox "Y+ removal distance reached by " & objProd.Name + End If + If posArray(10) < aRemovalDistances(i1, 3) Then + productReachedFinalPosition = True + 'MsgBox "Y- removal distance reached by " & objProd.Name + End If + If posArray(11) > aRemovalDistances(i1, 4) Then + productReachedFinalPosition = True + 'MsgBox "Z+ removal distance reached by " & objProd.Name + End If + If posArray(11) < aRemovalDistances(i1, 5) Then + productReachedFinalPosition = True + 'MsgBox "Z- removal distance reached by " & objProd.Name + End If + End Function + + Function productHasValidDisassDir(i1 As Integer, disassDir(,) As Object) As Boolean + productHasValidDisassDir = False + Dim j As Integer + For j = 0 To 11 + If disassDir(i1, j) = 1 Then + productHasValidDisassDir = True + Exit For + End If + Next j + End Function + + Function Tree(s1, q) + + For Each s2 In s1.Products + Tree(s2, q) + Next + + Dim parentAssy As Object + parentAssy = s1.Parent.Parent + + If StrComp(TypeName(parentAssy), "Product") = 0 Then + parentAssy.ReferenceProduct.Products.Item(s1.Name).Name = CStr(s1.PartNumber) & CStr("." & q) + q = q + 1 + End If + + End Function + + Private Sub RenameSingleLevel(ByRef oCurrentProd As Product) + + On Error Resume Next + + 'More declarations + Dim ItemToRename As Product + Dim ToRenamePartNumber As String + Dim lNumberOfItems As Long + Dim RenameArray(2000) As String + Dim i As Integer + Dim j As Integer + Dim k As Integer + + oCurrentProd = oCurrentProd.ReferenceProduct 'You have to work with the "ReferenceProduct" object + lNumberOfItems = oCurrentProd.Products.Count + + 'For i = 1 To lNumberOfItems 'Clear out the rename array + ' RenameArray(i) = "" 'Don't know if this is necessary + 'Next + + 'Run through this loop once, to set everything to a dummy name, to avoid naming conflicts + For i = 1 To lNumberOfItems 'Cycle through the assembly's children + ItemToRename = oCurrentProd.Products.Item(i) 'Declare which item we are working on + + ToRenamePartNumber = ItemToRename.PartNumber 'Get the Part Number + 'ToRenamePartNumber = ItemToRename.DescriptionRef 'Toggle these two lines for testing + + RenameArray(i) = ToRenamePartNumber 'Building the list of part names for the numbering loop + + k = 0 'Numbering Loop + For j = 1 To i 'This loop checks and sets the instance number + If RenameArray(j) = ToRenamePartNumber Then + k = k + 1 + End If + Next + CATIA.StatusBar = ItemToRename.Name & " > " & ToRenamePartNumber & "." & k + 'MsgBox ItemToRename.Name & " / " & ToRenamePartNumber & "." & k 'This line is for testing only + ItemToRename.Name = ToRenamePartNumber & "TEMP." & k 'Set the new instance name, to a TEMP dummy value + + Next + + 'Run through this loop to set the name finally, then the recursion call + For i = 1 To lNumberOfItems + ItemToRename = oCurrentProd.Products.Item(i) + + ToRenamePartNumber = ItemToRename.PartNumber 'Toggle these two lines for testing + 'ToRenamePartNumber = ItemToRename.DescriptionRef 'Toggle these two lines for testing + + RenameArray(i) = ToRenamePartNumber + + k = 0 + For j = 1 To i + If RenameArray(j) = ToRenamePartNumber Then + k = k + 1 + End If + Next + + CATIA.StatusBar = ItemToRename.Name & " > " & ToRenamePartNumber & "." & k + 'MsgBox ItemToRename.Name & " / " & ToRenamePartNumber & "." & k 'For testing + + ItemToRename.Name = ToRenamePartNumber & "." & k 'Set the new instance name final + + If ItemToRename.Products.Count <> 0 Then 'Recursive Call for version 0.1.2 + If oList.exists(ItemToRename.PartNumber) Then GoTo Finish + If ItemToRename.PartNumber = ItemToRename.ReferenceProduct.Parent.Product.PartNumber Then oList.Add(ItemToRename.PartNumber, 1) + Call RenameSingleLevel(ItemToRename) + End If + +Finish: + Next + + End Sub + + Function GetProductIndex(objProd As Product, cProds As ArrayList) As Integer + Dim produkt As Product + Dim intAns As Integer + intAns = 0 + For Each produkt In cProds + If produkt.Name = objProd.Name Then + GetProductIndex = intAns + Exit Function + End If + intAns = intAns + 1 + Next produkt + Return intAns + End Function + + Function BoundingBoxesOverlap(int_i As Integer, iStaticProduct As Integer) As Boolean + If aPartBBGlob(int_i, 1) >= aPartBBGlob(iStaticProduct, 0) Or aPartBBGlob(int_i, 0) <= aPartBBGlob(iStaticProduct, 1) Then + If aPartBBGlob(int_i, 3) >= aPartBBGlob(iStaticProduct, 2) Or aPartBBGlob(int_i, 2) <= aPartBBGlob(iStaticProduct, 3) Then + If aPartBBGlob(int_i, 5) >= aPartBBGlob(iStaticProduct, 4) Or aPartBBGlob(int_i, 4) <= aPartBBGlob(iStaticProduct, 5) Then + Return False + End If + End If + End If + Return True + End Function + + Sub ExportBBVolumes() + 'Use Excel + Dim objExcel As Microsoft.Office.Interop.Excel.Application + objExcel = CreateObject("Excel.Application") + objExcel.Visible = True + objExcel.Workbooks.Add() + objExcel.ActiveWorkbook.Sheets.Add.Name = "BB Volumes" + Dim objSheet1 As Object + objSheet1 = objExcel.ActiveWorkbook.Worksheets(1) + 'Write data + objSheet1.Cells(1, 1).Value = "Product" + objSheet1.Cells(1, 2).Value = "BB volume" + For int_i = 0 To cRelevantProducts.Count - 1 + Dim dPartBBVolume As Double + dPartBBVolume = (aPartBBGlob(int_i, 0) - aPartBBGlob(int_i, 1)) * (aPartBBGlob(int_i, 2) - aPartBBGlob(int_i, 3)) * (aPartBBGlob(int_i, 4) - aPartBBGlob(int_i, 5)) + objSheet1.Cells(int_i + 2, 1).Value = cRelevantProducts.Item(int_i).Name + objSheet1.Cells(int_i + 2, 2).Value = dPartBBVolume + Next int_i + 'Save and close excel workbook + objExcel.ActiveWorkbook.SaveAs(Filename:=xlsPath & xlsFileName & "_BB Volumes.xlsx") + objExcel.ActiveWorkbook.Close(SaveChanges:=True) + 'close the excel application + objExcel.Quit() + ReleaseObject(objExcel) + End Sub + + Private Sub ReleaseObject(ByVal obj As Object) + Try + Dim intRel As Integer = 0 + Do + intRel = System.Runtime.InteropServices.Marshal.ReleaseComObject(obj) + Loop While intRel > 0 + 'MsgBox("Final Released obj # " & intRel) + Catch ex As Exception + MsgBox("Error releasing object" & ex.ToString) + obj = Nothing + Finally + GC.Collect() + End Try + End Sub + + Sub ShowForm() + 'Create a new form to input algorithm specifications first + 'Dim Form2 As Form = New Form() + Me.Text = "Algorithm specifications" + Me.Size = New System.Drawing.Size(350, 400) + 'Create elements for parameter inputs + 'Code variant for BB calculation + 'Dim BBCodeComboBox As ComboBox = New ComboBox() + BBCodeComboBox.Items.Add(1) + BBCodeComboBox.Items.Add(2) + BBCodeComboBox.Location = New System.Drawing.Point(200, 20) + BBCodeComboBox.Size = New System.Drawing.Size(50, 20) + BBCodeComboBox.DropDownStyle = ComboBoxStyle.DropDownList + Dim Label1 As System.Windows.Forms.Label = New System.Windows.Forms.Label() + Label1.Text = "Bounding Box code type" + Label1.Location = New System.Drawing.Point(20, 20) + Label1.Size = New System.Drawing.Size(150, 20) + 'Projection check + 'Dim BBPCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox() + BBPCCheckBox.Location = New System.Drawing.Point(200, 50) + Dim Label2 As System.Windows.Forms.Label = New System.Windows.Forms.Label() + Label2.Text = "BB projection check" + Label2.Location = New System.Drawing.Point(20, 50) + Label2.Size = New System.Drawing.Size(150, 20) + 'Connectivity check + 'Dim CCCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox() + CCCheckBox.Location = New System.Drawing.Point(200, 80) + Dim Label3 As System.Windows.Forms.Label = New System.Windows.Forms.Label() + Label3.Text = "Connectivity check" + Label3.Location = New System.Drawing.Point(20, 80) + Label3.Size = New System.Drawing.Size(150, 20) + 'Automatic step + 'Dim AutoStepCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox() + AutoStepCheckBox.Location = New System.Drawing.Point(200, 110) + Dim Label4 As System.Windows.Forms.Label = New System.Windows.Forms.Label() + Label4.Text = "Automatic step" + Label4.Location = New System.Drawing.Point(20, 110) + Label4.Size = New System.Drawing.Size(150, 20) + 'Step + 'Dim StepTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox() + StepTextBox.Text = 5 + StepTextBox.Location = New System.Drawing.Point(200, 140) + StepTextBox.Size = New System.Drawing.Size(50, 20) + Dim Label5 As System.Windows.Forms.Label = New System.Windows.Forms.Label() + Label5.Text = "Step [mm]" + Label5.Location = New System.Drawing.Point(20, 140) + Label5.Size = New System.Drawing.Size(150, 20) + 'Collision sensitivity + 'Dim CollSensTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox() + CollSensTextBox.Text = 2 + CollSensTextBox.Location = New System.Drawing.Point(200, 170) + CollSensTextBox.Size = New System.Drawing.Size(50, 20) + Dim Label6 As System.Windows.Forms.Label = New System.Windows.Forms.Label() + Label6.Text = "Collision sensitivity [mm]" + Label6.Location = New System.Drawing.Point(20, 170) + Label6.Size = New System.Drawing.Size(150, 20) + 'Choice of extraction direction + 'Dim ExtractDirCheckBox As System.Windows.Forms.CheckBox = New System.Windows.Forms.CheckBox() + ExtractDirCheckBox.Location = New System.Drawing.Point(200, 200) + Dim Label7 As System.Windows.Forms.Label = New System.Windows.Forms.Label() + Label7.Text = "Choice of disassembly axis" + Label7.Location = New System.Drawing.Point(20, 200) + Label7.Size = New System.Drawing.Size(150, 20) + 'Number of disassembly axis + 'Dim AxisComboBox As ComboBox = New ComboBox() + AxisComboBox.Items.Add(6) + AxisComboBox.Items.Add(12) + AxisComboBox.Location = New System.Drawing.Point(200, 230) + AxisComboBox.Size = New System.Drawing.Size(50, 20) + AxisComboBox.DropDownStyle = ComboBoxStyle.DropDownList + Dim Label8 As System.Windows.Forms.Label = New System.Windows.Forms.Label() + Label8.Text = "Number of disassembly axis" + Label8.Location = New System.Drawing.Point(20, 230) + Label8.Size = New System.Drawing.Size(150, 20) + 'Desired name of the output Excel file + 'Dim XLSTextBox As System.Windows.Forms.TextBox = New System.Windows.Forms.TextBox() + XLSTextBox.Text = "Product" + XLSTextBox.Location = New System.Drawing.Point(200, 260) + Dim Label9 As System.Windows.Forms.Label = New System.Windows.Forms.Label() + Label9.Text = "Excel file name" + Label9.Location = New System.Drawing.Point(20, 260) + Label9.Size = New System.Drawing.Size(150, 20) + 'OK button + 'Dim OKButton As System.Windows.Forms.Button = New System.Windows.Forms.Button() + OKButton.Text = "Accept parameters" + OKButton.Location = New System.Drawing.Point(100, 310) + OKButton.Size = New System.Drawing.Size(150, 40) + + 'Add control elements to the form + Me.Controls.Add(Label1) + Me.Controls.Add(Label2) + Me.Controls.Add(Label3) + Me.Controls.Add(Label4) + Me.Controls.Add(Label5) + Me.Controls.Add(Label6) + Me.Controls.Add(Label7) + Me.Controls.Add(Label8) + Me.Controls.Add(Label9) + Me.Controls.Add(BBCodeComboBox) + Me.Controls.Add(BBPCCheckBox) + Me.Controls.Add(CCCheckBox) + Me.Controls.Add(AutoStepCheckBox) + Me.Controls.Add(StepTextBox) + Me.Controls.Add(CollSensTextBox) + Me.Controls.Add(ExtractDirCheckBox) + Me.Controls.Add(AxisComboBox) + Me.Controls.Add(XLSTextBox) + Me.Controls.Add(OKButton) + + Me.ShowDialog() + End Sub + + Private Sub OKButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles OKButton.Click + iBoundingBoxCode = BBCodeComboBox.SelectedItem + bBoundingBoxProjectionCheck = BBPCCheckBox.Checked + bConnectivityCheck = CCCheckBox.Checked + bAutomaticStep = AutoStepCheckBox.Checked + dCollSens = CDbl(CollSensTextBox.Text) + bChooseExtractionDirection = ExtractDirCheckBox.Checked + intJ = AxisComboBox.SelectedItem + xlsFileName = XLSTextBox.Text + Debug.Print("Parameters accepted") + Me.Hide() + Me.CatMain() + End Sub + +End Class + + diff --git a/CatiaNetTest/CatiaNetTest.vbproj b/CatiaNetTest/CatiaNetTest.vbproj index 9ae2bfb7dd98e22ff43ca1c5c210655c2415e5ac..54f63d8db398705bffc53bd7fc67d45c035d5e97 100644 --- a/CatiaNetTest/CatiaNetTest.vbproj +++ b/CatiaNetTest/CatiaNetTest.vbproj @@ -75,6 +75,9 @@ <ItemGroup> <Compile Include="AndOrDataExtraction.vb" /> <Compile Include="AssemblyTiers2.vb" /> + <Compile Include="AssemblyTiers3.vb"> + <SubType>Form</SubType> + </Compile> <Compile Include="Form1.vb"> <SubType>Form</SubType> </Compile> diff --git a/CatiaNetTest/Form1.vb b/CatiaNetTest/Form1.vb index 23cc7fa4b6bf0d4850c10b8834b3288675d25c07..0856c0a39fcf4a099934f785bde3284a541a5572 100644 --- a/CatiaNetTest/Form1.vb +++ b/CatiaNetTest/Form1.vb @@ -30,7 +30,7 @@ Public Class Form1 Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click - Dim myAssemblyTiers As AssemblyTiers2 = New AssemblyTiers2() + Dim myAssemblyTiers As AssemblyTiers3 = New AssemblyTiers3() Try myAssemblyTiers.ShowForm() diff --git a/CatiaNetTest/bin/Debug/CatiaNetTest.exe b/CatiaNetTest/bin/Debug/CatiaNetTest.exe index c3ac95e63787de3995e67465a3f9fee091463de0..216c8c5cf4990728a1103afa56464a8bd6f5a1bf 100644 Binary files a/CatiaNetTest/bin/Debug/CatiaNetTest.exe and b/CatiaNetTest/bin/Debug/CatiaNetTest.exe differ diff --git a/CatiaNetTest/bin/Debug/CatiaNetTest.pdb b/CatiaNetTest/bin/Debug/CatiaNetTest.pdb index 76f93b5c5d754a065f98f46d404716637806907c..2fc81a9baeb64153c5772df70e411864f0fbf849 100644 Binary files a/CatiaNetTest/bin/Debug/CatiaNetTest.pdb and b/CatiaNetTest/bin/Debug/CatiaNetTest.pdb differ diff --git a/CatiaNetTest/obj/Debug/CatiaNetTest.exe b/CatiaNetTest/obj/Debug/CatiaNetTest.exe index c3ac95e63787de3995e67465a3f9fee091463de0..216c8c5cf4990728a1103afa56464a8bd6f5a1bf 100644 Binary files a/CatiaNetTest/obj/Debug/CatiaNetTest.exe and b/CatiaNetTest/obj/Debug/CatiaNetTest.exe differ diff --git a/CatiaNetTest/obj/Debug/CatiaNetTest.pdb b/CatiaNetTest/obj/Debug/CatiaNetTest.pdb index 76f93b5c5d754a065f98f46d404716637806907c..2fc81a9baeb64153c5772df70e411864f0fbf849 100644 Binary files a/CatiaNetTest/obj/Debug/CatiaNetTest.pdb and b/CatiaNetTest/obj/Debug/CatiaNetTest.pdb differ diff --git a/CatiaNetTest/obj/Debug/CatiaNetTest.vbprojAssemblyReference.cache b/CatiaNetTest/obj/Debug/CatiaNetTest.vbprojAssemblyReference.cache index 6eb141be4bee0ee5c65bd86c64f00139b3982321..15398822a35bb52910b533ab170a2c9b01cc9256 100644 Binary files a/CatiaNetTest/obj/Debug/CatiaNetTest.vbprojAssemblyReference.cache and b/CatiaNetTest/obj/Debug/CatiaNetTest.vbprojAssemblyReference.cache differ