diff --git a/CatiaNetTest/AndOrDataExtraction.vb b/CatiaNetTest/AndOrDataExtraction.vb index ce6bec4f319946779e1300d8152b21a7d4c8e921..c0b1e046abef1884107f2a77c5a3001054c1d66e 100644 --- a/CatiaNetTest/AndOrDataExtraction.vb +++ b/CatiaNetTest/AndOrDataExtraction.vb @@ -79,9 +79,11 @@ Public Class AndOrDataExtraction Dim l2 As Integer = prt(1).Count 'Check both subassemblies for connectedness If SubassemblyIsConnected(prt(0)) = False Then + Debug.Print("First subassembly not connected!") Continue For End If If SubassemblyIsConnected(prt(1)) = False Then + Debug.Print("Second subassembly not connected!") Continue For End If 'Check whether disassembly is possible by checking for @@ -130,6 +132,8 @@ Public Class AndOrDataExtraction nodes.Add(prt(1)) AndOrGraph(prt(1), nodes) End If + Else + Debug.Print("No feasible assembly directions found!") End If Next @@ -288,7 +292,7 @@ Public Class AndOrDataExtraction For i = 0 To cRelevantProducts.Count - 1 '########## this won't work if part document name is not = part number ###### - ''Dim partI As Part + 'Dim partI As Part Dim prodI As Product prodI = cRelevantProducts.Item(i) Dim docName As String diff --git a/CatiaNetTest/AssemblyTiers2.vb b/CatiaNetTest/AssemblyTiers2.vb index cb54f91d2f3f3f38dbac3301948abe0db8938c94..1ab43c67e075eaacfe6713adaffc64c79f208f51 100644 --- a/CatiaNetTest/AssemblyTiers2.vb +++ b/CatiaNetTest/AssemblyTiers2.vb @@ -10,6 +10,7 @@ Imports Microsoft.Office.Interop.Excel Public Class AssemblyTiers2 + Public bCoherenceCheck As Boolean Public intStep As Integer Public dCollSens As Double Public intParts As Integer @@ -23,6 +24,7 @@ Public Class AssemblyTiers2 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 @@ -170,10 +172,11 @@ Public Class AssemblyTiers2 Debug.Print("Number of faces in assembly: " & CStr(intNumFaces)) 'Collision parameters - 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) + '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) + intStep = 13 Debug.Print("Movement step: " & CStr(intStep)) dCollSens = 2 @@ -221,6 +224,18 @@ Public Class AssemblyTiers2 Dim bInitPosRecorded(cRelevantProducts.Count - 1) As Boolean Dim bDeactivated(cRelevantProducts.Count - 1) As Boolean + 'Before trying to remove a component, check whether it would break liaison graph coherence / connectedness + bCoherenceCheck = True + Dim coherenceCheckNodeIndices As New List(Of Integer) + If bCoherenceCheck Then + Dim componentIndex As Integer + componentIndex = 0 + For Each oComponent In cRelevantProducts + coherenceCheckNodeIndices.Add(componentIndex) + componentIndex = componentIndex + 1 + Next oComponent + End If + intI = cRelevantProducts.Count - 1 'the index of base components will be simply skipped (cRelevantProducts includes cBaseProducts, unlike in the paper!) intJ = 6 'number of disassembly directions (6 - only global axes, 12 - including local axes) intTier = 1 'counts current disassembly tier (lower number means earlier disassembly possible) - this gets reversed in the end @@ -256,6 +271,11 @@ Public Class AssemblyTiers2 Dim StartTime As DateTime StartTime = Now + 'Liaison graph extraction for coherence checks + If bCoherenceCheck Then + Liaison() + End If + Do 'Processing next Product @@ -269,6 +289,32 @@ Public Class AssemblyTiers2 GoTo entry0 End If + If bCoherenceCheck Then + 'If a component is allowed to be moved, check whether removing it will break up the coherence of product liaison graph + 'Remove int_i from index list + Dim listIndex As Integer + listIndex = 0 + For Each partIndex In coherenceCheckNodeIndices + If partIndex = int_i Then + Exit For + Else + listIndex = listIndex + 1 + End If + Next + coherenceCheckNodeIndices.RemoveAt(listIndex) + 'Check whether all node of LG can be visited from any other node (= connected graph) + If SubassemblyIsConnected(coherenceCheckNodeIndices) Then + 'Put int_i back at listIndex + coherenceCheckNodeIndices.Insert(listIndex, int_i) + Else + 'If coherence will be broken, skip this component + Debug.Print("Removing " & product1.Name & " would violate liaison graph coherence!") + 'Put int_i back at listIndex + coherenceCheckNodeIndices.Insert(listIndex, int_i) + GoTo exit2 + End If + End If + 'Remember initial position P_i (initPos) Dim initPos(11) Dim oPosition1 As Object @@ -293,9 +339,9 @@ Public Class AssemblyTiers2 Dim iStaticProduct As Integer For iStaticProduct = 0 To cRelevantProducts.Count - 1 If iStaticProduct <> int_i And Not bDeactivated(iStaticProduct) Then - If BoundingBoxesOverlap(int_i, iStaticProduct) Then - group2.AddExplicit(cRelevantProducts.Item(iStaticProduct)) - End If + 'If BoundingBoxesOverlap(int_i, iStaticProduct) Then + group2.AddExplicit(cRelevantProducts.Item(iStaticProduct)) + 'End If End If Next iStaticProduct @@ -361,7 +407,7 @@ entry1: 'if the disassembly tier is 1 lower (attention: tiers get reversed in the end to the assembly tiers!) If secTier = intTier - 1 And Not (secTier = 0 And intTier = 1) Then - Debug.Print("Collision with higher tier: " & oConflict1.FirstProduct.Name & " - " & oConflict1.SecondProduct.Name & " = " & oConflict1.Value) + '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 @@ -392,6 +438,21 @@ exit1: 'all directions were checked total_coll = total_coll + intJ Debug.Print("Disassembly trials: " & total_coll) + 'if this component can be disassembled, remove its index from coherence check list + If bCoherenceCheck And productHasValidDisassDir(int_i, disassDir) Then + Dim listInd As Integer + listInd = 0 + For Each partIndex In coherenceCheckNodeIndices + 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) + coherenceCheckNodeIndices.RemoveAt(listInd) + End If +exit2: int_i = int_i + 1 int_i_cycle = int_i_cycle + 1 int_j = 0 @@ -794,7 +855,114 @@ exitCD: 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 @@ -1550,7 +1718,7 @@ exitCD: 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) + 'Debug.Print("Clash detected: " & oConflict.FirstProduct.Name & " - " & oConflict.SecondProduct.Name & " = " & oConflict.Value) Exit For End If End If diff --git a/CatiaNetTest/HierarchicalAssemblyTiers.vb b/CatiaNetTest/HierarchicalAssemblyTiers.vb index a6dab04571715d2babb81a514eb056f3b946cb5e..ac763d0145119196f15c774b1412cf8553941c5e 100644 --- a/CatiaNetTest/HierarchicalAssemblyTiers.vb +++ b/CatiaNetTest/HierarchicalAssemblyTiers.vb @@ -139,7 +139,7 @@ Public Class HierarchicalAssemblyTiers For j = 0 To cElements.Count - 1 '########## this won't work if part document name is not = part number ###### - ''Dim partI As Part + 'Dim partI As Part Dim prodI As Product prodI = cElements.Item(j) Dim docName As String @@ -181,10 +181,11 @@ Public Class HierarchicalAssemblyTiers Debug.Print("Number of faces in assembly: " & CStr(intNumFaces)) 'Collision parameters - 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) + '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) + intStep = 54 Debug.Print("Movement step: " & CStr(intStep)) dCollSens = 2 @@ -727,9 +728,12 @@ exitCD: 'Once we are done on this level, generate precedence diagrams for each subassembly recursively Dim subassembly As Product For Each subassembly In cRelevantProducts - Dim leafProducts As New ArrayList - ExtractProducts(subassembly, leafProducts) - If leafProducts.Count > 5 Then + 'Dim leafProducts As New ArrayList + 'ExtractProducts(subassembly, leafProducts) + 'If leafProducts.Count > 5 Then + ' AssemblyTiersDetermination(subassembly) + 'End If + If subassembly.Products.Count > 5 Then AssemblyTiersDetermination(subassembly) End If Next subassembly diff --git a/CatiaNetTest/bin/Debug/CatiaNetTest.exe b/CatiaNetTest/bin/Debug/CatiaNetTest.exe index 6831f4de9d7aa37f0171ea57245af57abe0e8f20..e09982ee09f61a910f46adf8c13a9e2a75aef273 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 8a459496ce726433a93890ed6461cd883cd898ae..10b8f13e3bd8bf2e5bad681d59d90b83f5d5131a 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 6831f4de9d7aa37f0171ea57245af57abe0e8f20..e09982ee09f61a910f46adf8c13a9e2a75aef273 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 8a459496ce726433a93890ed6461cd883cd898ae..10b8f13e3bd8bf2e5bad681d59d90b83f5d5131a 100644 Binary files a/CatiaNetTest/obj/Debug/CatiaNetTest.pdb and b/CatiaNetTest/obj/Debug/CatiaNetTest.pdb differ diff --git a/CatiaNetTest/obj/Debug/CatiaNetTest.vbproj.ResolveComReference.cache b/CatiaNetTest/obj/Debug/CatiaNetTest.vbproj.ResolveComReference.cache index 2dd5a0db036cfd6ded31ddbe13c62f2f21104559..f9fd5b2db8d07a16c65f5d449088c3156f85779a 100644 Binary files a/CatiaNetTest/obj/Debug/CatiaNetTest.vbproj.ResolveComReference.cache and b/CatiaNetTest/obj/Debug/CatiaNetTest.vbproj.ResolveComReference.cache differ diff --git a/CatiaNetTest/obj/Debug/CatiaNetTest.vbprojAssemblyReference.cache b/CatiaNetTest/obj/Debug/CatiaNetTest.vbprojAssemblyReference.cache index 4788ac6375fce3d9e11ed6d39b91e57428ed94aa..7e0968d4938a6fd3504f231b9b910fa003dd79d5 100644 Binary files a/CatiaNetTest/obj/Debug/CatiaNetTest.vbprojAssemblyReference.cache and b/CatiaNetTest/obj/Debug/CatiaNetTest.vbprojAssemblyReference.cache differ