//This function gets the transform matrix of a given component respect to its father. public static MyTransformMatrix GetTransformMatrix(Component2 swComponent, SldWorks swApplication) { var componentXForm = swComponent.GetTotalTransform(true); var newMyTransformMatrix = new MyTransformMatrix(); if (componentXForm != null) { var xForm = (Array)componentXForm.ArrayData; double[,] newRotationMatrix = new double[3, 3] { { (double)xForm.GetValue(0), (double)xForm.GetValue(3), (double)xForm.GetValue(6) }, { (double)xForm.GetValue(1), (double)xForm.GetValue(4), (double)xForm.GetValue(7) }, { (double)xForm.GetValue(2), (double)xForm.GetValue(5), (double)xForm.GetValue(8) } }; double[] newTranslationalVector = { (double)xForm.GetValue(9), (double)xForm.GetValue(10), (double)xForm.GetValue(11) }; newMyTransformMatrix = new MyTransformMatrix(newRotationMatrix, newTranslationalVector, (double)xForm.GetValue(12)); } else { swApplication.SendMsgToUser("La componente " + swComponent.Name + " ha matrice di trasformazione NULLA ---->> ERRORE."); } return(newMyTransformMatrix); }
public static MyRepeatedComponent ComputeNewRepeatedComponent(SldWorks swApplication, Component2 component2, int idCorrespondingNode, MyTransformMatrix newRelativeTransformMatrix, int indexRepEntity, bool newIsLeaf) { // Aggiunto calcolo dell'entità ripetuta alla parte. var currentModel = component2.GetModelDoc2(); var entityList = (List <Entity>)AssemblyTraverse.KL_GetPartFaces(currentModel, component2.Name2, swApplication); double[,] compositionMatrixOfComponentPart = new double[4, 4] { { (double)newRelativeTransformMatrix.RotationMatrix[0, 0], (double)newRelativeTransformMatrix.RotationMatrix[0, 1], (double)newRelativeTransformMatrix.RotationMatrix[0, 2], (double)newRelativeTransformMatrix.TranslationVector[0] }, { (double)newRelativeTransformMatrix.RotationMatrix[1, 0], (double)newRelativeTransformMatrix.RotationMatrix[1, 1], (double)newRelativeTransformMatrix.RotationMatrix[1, 2], (double)newRelativeTransformMatrix.TranslationVector[1] }, { (double)newRelativeTransformMatrix.RotationMatrix[2, 0], (double)newRelativeTransformMatrix.RotationMatrix[2, 1], (double)newRelativeTransformMatrix.RotationMatrix[2, 2], (double)newRelativeTransformMatrix.TranslationVector[2] }, { 0.0, 0.0, 0.0, 1 } }; //swApplication.SendMsgToUser("Calcolo repeated entity di " + component2.Name2 + "\nnumero facce " + entityList.Count); MyRepeatedEntity newRepeatedEntity = ExtractInfoFromBRep.KLBuildRepeatedEntity( entityList, indexRepEntity, compositionMatrixOfComponentPart, swApplication); //swApplication.SendMsgToUser("Ha " + newRepeatedEntity.listOfVertices.Count + " vertici\n" + newRepeatedEntity.listOfAddedVertices.Count + " vertici aggiunti"); // Fine calcolo entità rip da aggiungere alla componente. var newMyComponent = new MyRepeatedComponent(component2, idCorrespondingNode, newRelativeTransformMatrix, newIsLeaf, newRepeatedEntity); return(newMyComponent); }
//This function takes a component and decomposes it in all the existing children. //For every children a MyTransformMatrix is computed. The computed transform matrix refers //to the given children component respect to its position in the original file //(such a matrix is obtained composing the MyTransformMatrix referred to the component //position respect to its father and the father's MyTransformMatrix). //If a children has other children it decomposes it too. public static void TraversAssemblyComponents(Component2 swComponent2, MyTransformMatrix fatherTransformMatrix, SldWorks swApplication) { //List of the lists of instances of the same file object: var ListOfMyListOfInstances = new List <MyListOfInstances>(); if (swComponent2 == null) { return; } var nameFile = "ClassifyComponents.txt"; //I take the children of the root component var swChildrenComponent = (Array)swComponent2.GetChildren(); int i = 0; foreach (Component2 component2 in swChildrenComponent) { //for each son I create a new ComputeNewRepeatedComponent var newRelativeTransformMatrix = AssemblyTraverse.GetTransformMatrix(component2, swApplication); var newTransformMatrix = fatherTransformMatrix.ComposeTwoTransformMatrix(newRelativeTransformMatrix, swApplication); bool newIsLeaf = component2.IGetChildrenCount() == 0; //If the current son is not a "leaf" component the function is recalled again: if (component2.IGetChildrenCount() != 0) { TraversAssemblyComponents(component2, newTransformMatrix, swApplication); } else { var newMyComponent = ComputeNewRepeatedComponent(swApplication, component2, 0, newRelativeTransformMatrix, i, newIsLeaf); //I verify if the list corresponding to this component already exists: //KLdebug.Print("-Componente # " + indexRepEntity + " di " + swComponent2.Name2, nameFile); string namePath = component2.GetPathName(); string nameFileComponent = namePath.Split('\\').Last(); //to get the last name after the last "\" //namePath = namePath.TrimEnd('-'); //string nameFileComponent = namePath.Remove((namePath.LastIndexOf('-') + 1)); //KLdebug.Print(" --->> namePath: " + namePath, "nomi.txt"); //KLdebug.Print(" --->> nameFileComponent: " + nameFileComponent, "nomi.txt"); //KLdebug.Print(" Matrice relativa", nameFile); //KLdebug.PrintTransformMatrix(newRelativeTransformMatrix, nameFile, swApplication); //KLdebug.Print(" Matrice assoluta", nameFile); //KLdebug.PrintTransformMatrix(newTransformMatrix, nameFile, swApplication); var indexOfFind = ListOfMyListOfInstances.FindIndex(list => list.Name == nameFileComponent); if (indexOfFind != -1) { //The list referred to this component already exists. I add it to the corresponding list //var newMyComponent = new ComputeNewRepeatedComponent(); //var newIndex = // ListOfMyListOfInstances[indexOfFind].ListOfMyComponent.Count + 1; //newMyComponent.RepeatedEntity.idRE = newIndex; ListOfMyListOfInstances[indexOfFind].ListOfMyComponent.Add(newMyComponent); //KLdebug.Print(" AGGIORNATA LISTA ESISTENTE: " + newMyComponent.Name + " con id" +newMyComponent.RepeatedEntity.idRE, nameFile); } //else //{ // //Check of the component satisfy other shape criteria (volume and percentage of type of surfaces) // var shapeComparison = AssemblyTraverse.KL_GetShapePart(component2, swApplication); // var statisticComparison = AssemblyTraverse.KL_GetStatisticPart(component2, // shapeComparison.Surface, swApplication); // var addCompForShape = false; // foreach (MyListOfInstances instance in ListOfMyListOfInstances) // { // var component = (Component2)instance.ListOfMyComponent.First().Component; // var shapeOriginal = AssemblyTraverse.KL_GetShapePart(component, swApplication); // var statisticOriginal = AssemblyTraverse.KL_GetStatisticPart(component, // shapeOriginal.Surface, // swApplication); // if (KLcriteriaCheck.Size.Volume(shapeOriginal, shapeComparison, swApplication)) // { // if (KLcriteriaCheck.Size.PercentageSurfacesType(statisticOriginal, statisticComparison, // swApplication)) // { // namePath = component.GetPathName(); // nameFileComponent = namePath.Split('\\').Last(); // //nameFileComponent = namePath; // indexOfFind = // ListOfMyListOfInstances.FindIndex(list => list.Name == nameFileComponent); // ListOfMyListOfInstances[indexOfFind].ListOfMyComponent.Add(newMyComponent); // addCompForShape = true; // break; // } // } // } // //The list referred to this component does not exist yet. I create it // if (!addCompForShape) // { // List<MyRepeatedComponent> newListOfComponentsOfListOfInstances = new List // <MyRepeatedComponent> // { // newMyComponent // }; // var newListOfInstances = new MyListOfInstances(nameFileComponent, // newListOfComponentsOfListOfInstances); // ListOfMyListOfInstances.Add(newListOfInstances); // //KLdebug.Print(" CREATA NUOVA LISTA nome:" + newListOfInstances.Name, nameFile); // } //} i++; } } }
public static void MainPatternSearch_Assembly(List <MyListOfInstances> ListOfMyListOfInstances, ModelDoc2 SwModel, SldWorks swApplication, ref StringBuilder fileOutput, out List <MyPatternOfComponents> listOfOutputPatternOut, out List <MyPatternOfComponents> listOfOutputPatternTwoOut) { //ListOfMyListOfInstances.Clear(); var identityTransformMatrix = new MyTransformMatrix(); //Update ListOfMyListOfInstances: //-delete list containing only one occurrence //-reorder the list by decreasing ordering respect to the number of occurrences ListOfMyListOfInstances.RemoveAll(list => list.ListOfMyComponent.Count == 1); var numOfListOfInstances = ListOfMyListOfInstances.Count; ListOfMyListOfInstances = ListOfMyListOfInstances.OrderByDescending(x => x.ListOfMyComponent.Count).ToList(); listOfOutputPatternOut = new List <MyPatternOfComponents>(); //list of output patterns found listOfOutputPatternTwoOut = new List <MyPatternOfComponents>(); //list of output patterns of length 2 found //Console.WriteLine("Numero istanze " + ListOfMyListOfInstances.Count); for (var k = 0; k < numOfListOfInstances; k++) { //Console.WriteLine("Analizzo istanza: " + ListOfMyListOfInstances[k].Name + " ripetuta " + ListOfMyListOfInstances[k].ListOfMyComponent.Count); var listOfOutputPattern = new List <MyPatternOfComponents>(); //list of output patterns found var listOfOutputPatternTwo = new List <MyPatternOfComponents>(); //list of output patterns of length 2 found var listOfComponents = new List <MyRepeatedComponent>(ListOfMyListOfInstances[k].ListOfMyComponent); //Verify if there exist coinciding origins: in that case that component is skipped //Otherwise the pexisting patterns are identified: //var listOfVertexOrigins = listOfComponents.Select(component2 => component2.Origin).ToList(); //var found = false; //var indexRepEntity = 0; //while (indexRepEntity < listOfVertexOrigins.Count - 1 && found == false) //{ // if (listOfVertexOrigins.FindIndex(origin => origin.Equals(listOfVertexOrigins[indexRepEntity]) && // listOfVertexOrigins.IndexOf(origin) != indexRepEntity) != -1) // { // found = true; // } // else // { // indexRepEntity++; // } //} //// Lo commento perché vorrei che non usasse indexRepEntity sistemi di riferimento per il riconoscimento, ma indexRepEntity vertici delle parti //if (found == false) //{ // AssemblyPatterns.FindPatternsOfComponents(listOfComponents, listOfVertexOrigins, // ref listOfOutputPattern, ref listOfOutputPatternTwo, SwModel, swApplication, ref fileOutput); //} //else //{ // swApplication.SendMsgToUser("Component '" + // ListOfMyListOfInstances[k].Name + "' cannot be processed. SKIPPED."); //} // Modifica aggiunta da Katia per il controllo delle facce var listCentroidWordRF = new List <MyVertex>(); //swApplication.SendMsgToUser("Analizzo " + ListOfMyListOfInstances[k].Name); //swApplication.SendMsgToUser("Nome istanza " + instance.Name); //swApplication.SendMsgToUser("Ho " + listOfComponents.Count + " componenti"); foreach (MyRepeatedComponent repeatedComponent in listOfComponents) { var sameIndex = listOfComponents.IndexOf(repeatedComponent); repeatedComponent.RepeatedEntity.idRE = sameIndex; var newRepeatedEntity = repeatedComponent.RepeatedEntity; if (newRepeatedEntity.listOfFaces.Any() && !repeatedComponent.IsSphere) { //swApplication.SendMsgToUser("Ci sono facce"); double[] centroidAffine = { newRepeatedEntity.centroid.x, newRepeatedEntity.centroid.y, newRepeatedEntity.centroid.z, 1 }; double scaleFactor = 1; double[,] compositionMatrixOfComponentPart = new double[4, 4] { { (double)repeatedComponent.Transform.RotationMatrix[0, 0], (double)repeatedComponent.Transform.RotationMatrix[0, 1], (double)repeatedComponent.Transform.RotationMatrix[0, 2], (double)repeatedComponent.Transform.TranslationVector[0] }, { (double)repeatedComponent.Transform.RotationMatrix[1, 0], (double)repeatedComponent.Transform.RotationMatrix[1, 1], (double)repeatedComponent.Transform.RotationMatrix[1, 2], (double)repeatedComponent.Transform.TranslationVector[1] }, { (double)repeatedComponent.Transform.RotationMatrix[2, 0], (double)repeatedComponent.Transform.RotationMatrix[2, 1], (double)repeatedComponent.Transform.RotationMatrix[2, 2], (double)repeatedComponent.Transform.TranslationVector[2] }, { 0.0, 0.0, 0.0, 1 } }; var newCentroid = Matrix.Multiply(compositionMatrixOfComponentPart, centroidAffine); var centroid = new MyVertex(newCentroid[0], newCentroid[1], newCentroid[2]); // Ho dovuto cambiare l'origine perché il find pattern a volte prende indexRepEntity centri dalla lista in input a volte lo estrae dalla repeated component. //repeatedComponent.Origin.x = newCentroid[0]; //repeatedComponent.Origin.y = newCentroid[1]; //repeatedComponent.Origin.z = newCentroid[2]; //listCentroidWordRF.Add(centroid); repeatedComponent.Origin.x = newRepeatedEntity.centroid.x; repeatedComponent.Origin.y = newRepeatedEntity.centroid.y; repeatedComponent.Origin.z = newRepeatedEntity.centroid.z; listCentroidWordRF.Add(newRepeatedEntity.centroid); //SwModel = swApplication.ActiveDoc; //SwModel.ClearSelection2(true); //SwModel.Insert3DSketch(); //SwModel.CreatePoint2(newRepeatedEntity.centroid.x, newRepeatedEntity.centroid.y, // newRepeatedEntity.centroid.z); //SwModel.InsertSketch(); // listOfOutputPattern.Clear(); // listOfOutputPatternTwo.Clear(); } // Se non ci sono facce verifico se è tutta freeform e uguale ad una sfera else if (repeatedComponent.IsSphere) { // Calcolo del centro di massa per trovare il pattern var body = (Body2)repeatedComponent.Component.GetBody(); var mass = (double[])body.GetMassProperties(0); var centerOfMass = new MyVertex(mass[0], mass[1], mass[2]); repeatedComponent.Origin.x = centerOfMass.x; repeatedComponent.Origin.y = centerOfMass.y; repeatedComponent.Origin.z = centerOfMass.z; listCentroidWordRF.Add(centerOfMass); //SwModel = swApplication.ActiveDoc; //SwModel.ClearSelection2(true); //SwModel.Insert3DSketch(); //SwModel.CreatePoint2(mass[0], mass[1], mass[2]); //SwModel.InsertSketch(); } } //swApplication.SendMsgToUser("Calcolo pattern " + listOfComponents[0].Name + "\ncomponenti " + listOfComponents.Count); if (listCentroidWordRF.Count == listOfComponents.Count) { AssemblyPatterns.KLFindPatternsOfComponents(listOfComponents, listCentroidWordRF, ref listOfOutputPattern, ref listOfOutputPatternTwo, SwModel, swApplication, ref fileOutput); } if (listOfOutputPattern.Any()) { foreach (var patternOfComponents in listOfOutputPattern) { listOfOutputPatternOut.Add(patternOfComponents); //swApplication.SendMsgToUser("Patern " + patternOfComponentse.typeOfMyPattern + " lunghezza " + patternOfComponentse.listOfMyRCOfMyPattern.Count); var listOfOriginsThisPattern = patternOfComponents.listOfMyRCOfMyPattern.Select(rc => rc.Origin).ToList(); var patternCentroid = ExtractInfoFromBRep.computeCentroidsOfVertices(listOfOriginsThisPattern); patternOfComponents.patternCentroid = patternCentroid; } } if (listOfOutputPatternTwo.Any()) { foreach (var patternOfComponentse in listOfOutputPatternTwo) { listOfOutputPatternTwoOut.Add(patternOfComponentse); //swApplication.SendMsgToUser("Patern " + patternOfComponentse.typeOfMyPattern + " lunghezza " + patternOfComponentse.listOfMyRCOfMyPattern.Count); } } } //} //It shows and print the detected patterns: //ShowAndPrintResults_Assembly(listOfOutputPatternOut, listOfOutputPatternTwoOut, SwModel, swApplication); ////Assigning of id numbers to the found MyPatternOfComponents ////(the id will be used in composed pattern search phase) ////At the same time, we draw the pattern origins //SwModel = swApplication.ActiveDoc; //SwModel.ClearSelection2(true); //SwModel.Insert3DSketch(); //var j = 0; //foreach (var pattern in listOfOutputPattern) //{ // pattern.idMyPattern = j; // j++; // var listOfOriginsThisPattern = // pattern.listOfMyRCOfMyPattern.Select(rc => rc.Origin).ToList(); // var patternCentroid = // ExtractInfoFromBRep.computeCentroidsOfVertices(listOfOriginsThisPattern); // pattern.patternCentroid = patternCentroid; // SwModel.CreatePoint2(pattern.patternCentroid.x, pattern.patternCentroid.y, // pattern.patternCentroid.z); //} //foreach (var pattern in listOfOutputPatternTwo) //{ // pattern.idMyPattern = j; // j++; // var listOfOriginsThisPattern = // pattern.listOfMyRCOfMyPattern.Select(rc => rc.Origin).ToList(); // var patternCentroid = // ExtractInfoFromBRep.computeCentroidsOfVertices(listOfOriginsThisPattern); // pattern.patternCentroid = patternCentroid; // SwModel.CreatePoint2(pattern.patternCentroid.x, pattern.patternCentroid.y, // pattern.patternCentroid.z); //} //SwModel.InsertSketch(); ////Patterns are subdivided in Line patterns and in Circle patterns: //var listOfOutputPatternLine = new List<MyPatternOfComponents>(); //var listOfOutputPatternCircum = new List<MyPatternOfComponents>(); //var nameFile = "ComposedPatterns_Assembly.txt"; //foreach (var pattern in listOfOutputPattern) //{ // if (pattern.pathOfMyPattern.GetType() == typeof (MyLine)) // { // listOfOutputPatternLine.Add(pattern); // KLdebug.Print("- pattern di tipo " + pattern.typeOfMyPattern, nameFile); // KLdebug.Print(" di lunghezza " + pattern.listOfMyRCOfMyPattern.Count, nameFile); // } // else // { // listOfOutputPatternCircum.Add(pattern); // KLdebug.Print("- pattern di tipo " + pattern.typeOfMyPattern, nameFile); // KLdebug.Print(" di lunghezza " + pattern.listOfMyRCOfMyPattern.Count, nameFile); // } //} //// >>>>>> COMPOSED PATTERN SEARCH: //List<MyComposedPatternOfComponents> listOfOutputComposedPattern; //List<MyComposedPatternOfComponents> listOfOutputComposedPatternTwo; //FindComposedPatternsOfComponents( // listOfOutputPatternLine, // listOfOutputPatternCircum, // out listOfOutputComposedPattern, // out listOfOutputComposedPatternTwo, // SwModel, swApplication, ref fileOutput); //ShowAndPrintResults_Assembly_ComposedPatterns(listOfOutputComposedPattern, // listOfOutputComposedPatternTwo, // SwModel, swApplication); }