//======================================================================= //function : Execute //purpose : //======================================================================= Standard_Integer GEOMImpl_Fillet1dDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_IFillet1d aCI (aFunction); Handle(GEOM_Function) aRefShape = aCI.GetShape(); TopoDS_Shape aShape = aRefShape->GetValue(); if (aShape.IsNull()) return 0; if (aShape.ShapeType() != TopAbs_WIRE) Standard_ConstructionError::Raise("Wrong arguments: polyline as wire must be given"); TopoDS_Wire aWire = TopoDS::Wire(aShape); double rad = aCI.GetR(); if ( rad < Precision::Confusion()) return 0; // collect vertices for make fillet TopTools_ListOfShape aVertexList; TopTools_MapOfShape mapShape; int aLen = aCI.GetLength(); if ( aLen > 0 ) { for (int ind = 1; ind <= aLen; ind++) { TopoDS_Shape aShapeVertex; if (GEOMImpl_ILocalOperations::GetSubShape (aWire, aCI.GetVertex(ind), aShapeVertex)) if (mapShape.Add(aShapeVertex)) aVertexList.Append( aShapeVertex ); } } else { // get all vertices from wire TopExp_Explorer anExp( aWire, TopAbs_VERTEX ); for ( ; anExp.More(); anExp.Next() ) { if (mapShape.Add(anExp.Current())) aVertexList.Append( anExp.Current() ); } } if (aVertexList.IsEmpty()) Standard_ConstructionError::Raise("Invalid input no vertices to make fillet"); //INFO: this algorithm implemented in assumption that user can select both // vertices of some edges to make fillet. In this case we should remember // already modified initial edges to take care in next fillet step TopTools_DataMapOfShapeShape anEdgeToEdgeMap; //iterates on vertices, and make fillet on each couple of edges //collect result fillet edges in list TopTools_ListOfShape aListOfNewEdge; // remember relation between initial and modified map TopTools_IndexedDataMapOfShapeListOfShape aMapVToEdges; TopExp::MapShapesAndAncestors( aWire, TopAbs_VERTEX, TopAbs_EDGE, aMapVToEdges ); TopTools_ListIteratorOfListOfShape anIt( aVertexList ); for ( ; anIt.More(); anIt.Next() ) { TopoDS_Vertex aV = TopoDS::Vertex( anIt.Value() ); if ( aV.IsNull() || !aMapVToEdges.Contains( aV ) ) continue; const TopTools_ListOfShape& aVertexEdges = aMapVToEdges.FindFromKey( aV ); if ( aVertexEdges.Extent() != 2 ) continue; // no input data to make fillet TopoDS_Edge anEdge1 = TopoDS::Edge( aVertexEdges.First() ); TopoDS_Edge anEdge2 = TopoDS::Edge( aVertexEdges.Last() ); // check if initial edges already modified in previous fillet operation if ( anEdgeToEdgeMap.IsBound( anEdge1 ) ) anEdge1 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge1 )); if ( anEdgeToEdgeMap.IsBound( anEdge2 ) ) anEdge2 = TopoDS::Edge(anEdgeToEdgeMap.Find( anEdge2 )); if ( anEdge1.IsNull() || anEdge2.IsNull() || anEdge1.IsSame( anEdge2 ) ) continue; //no input data to make fillet // create plane on 2 edges gp_Pln aPlane; if ( !takePlane(anEdge1, anEdge2, aV, aPlane) ) continue; // seems edges does not belong to same plane or parallel (fillet can not be build) GEOMImpl_Fillet1d aFilletAlgo(anEdge1, anEdge2, aPlane); if ( !aFilletAlgo.Perform(rad) ) continue; // can not create fillet with given radius // take fillet result in given vertex TopoDS_Edge aModifE1, aModifE2; TopoDS_Edge aNewE = aFilletAlgo.Result(BRep_Tool::Pnt(aV), aModifE1, aModifE2); if (aNewE.IsNull()) continue; // no result found // add new created edges and take modified edges aListOfNewEdge.Append( aNewE ); // check if face edges modified, // if yes, than map to original edges (from vertex-edges list), because edges can be modified before if (aModifE1.IsNull() || !anEdge1.IsSame( aModifE1 )) addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.First()), aModifE1 ); if (aModifE2.IsNull() || !anEdge2.IsSame( aModifE2 )) addEdgeRelation( anEdgeToEdgeMap, TopoDS::Edge(aVertexEdges.Last()), aModifE2 ); } if ( anEdgeToEdgeMap.IsEmpty() && aListOfNewEdge.IsEmpty() ) { StdFail_NotDone::Raise("1D Fillet can't be computed on the given shape with the given radius"); return 0; } // create new wire instead of original for ( TopExp_Explorer anExp( aWire, TopAbs_EDGE ); anExp.More(); anExp.Next() ) { TopoDS_Shape anEdge = anExp.Current(); if ( !anEdgeToEdgeMap.IsBound( anEdge ) ) aListOfNewEdge.Append( anEdge ); else if (!anEdgeToEdgeMap.Find( anEdge ).IsNull()) aListOfNewEdge.Append( anEdgeToEdgeMap.Find( anEdge ) ); } GEOMImpl_IShapesOperations::SortShapes( aListOfNewEdge ); BRepBuilderAPI_MakeWire aWireTool; aWireTool.Add( aListOfNewEdge ); aWireTool.Build(); if (!aWireTool.IsDone()) return 0; aWire = aWireTool.Wire(); aFunction->SetValue(aWire); log.SetTouched(Label()); return 1; }
void Tesselate_Presentation::tesselateShape(const TopoDS_Shape& aShape) { // setResultTitle("Tesselate shape"); TCollection_AsciiString aText = ( "/////////////////////////////////////////////////////////////////" EOL "// Tesselate shape." EOL "/////////////////////////////////////////////////////////////////" EOL EOL ) ; Standard_Real aDeflection = DATA[myIndex][0]; Standard_Integer aNumOfFace = (Standard_Integer)DATA[myIndex][1]; Standard_Integer aNumOfEdge = (Standard_Integer)DATA[myIndex][2]; aText += "Standard_Real aDeflection;" EOL "// aDeflection = ... ;" EOL EOL "// removes all the triangulations of the faces ," EOL "//and all the polygons on the triangulations of the edges:" EOL "BRepTools::Clean(aShape);" EOL EOL "// adds a triangulation of the shape aShape with the deflection aDeflection:" EOL "BRepMesh::Mesh(aShape,aDeflection);" EOL EOL "TopExp_Explorer aExpFace,aExpEdge;" EOL "for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next())" EOL "{ " EOL " TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());" EOL " TopLoc_Location aLocation;" EOL EOL " // takes the triangulation of the face aFace:" EOL " Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation);" EOL EOL " if(!aTr.IsNull()) // if this triangulation is not NULL" EOL " { " EOL " // takes the array of nodes for this triangulation:" EOL " const TColgp_Array1OfPnt& aNodes = aTr->Nodes();" EOL " // takes the array of triangles for this triangulation:" EOL " const Poly_Array1OfTriangle& triangles = aTr->Triangles();" EOL EOL " // create array of node points in absolute coordinate system" EOL " TColgp_Array1OfPnt aPoints(1, aNodes.Length());" EOL " for( Standard_Integer i = 1; i < aNodes.Length()+1; i++)" EOL " aPoints(i) = aNodes(i).Transformed(aLocation);" EOL EOL " // Takes the node points of each triangle of this triangulation." EOL " // takes a number of triangles:" EOL " Standard_Integer nnn = aTr->NbTriangles();" EOL " Standard_Integer nt,n1,n2,n3;" EOL " for( nt = 1 ; nt < nnn+1 ; nt++)" EOL " {" EOL " // takes the node indices of each triangle in n1,n2,n3:" EOL " triangles(nt).Get(n1,n2,n3);" EOL " // takes the node points:" EOL " gp_Pnt aPnt1 = aPoints(n1);" EOL " gp_Pnt aPnt2 = aPoints(n2);" EOL " gp_Pnt aPnt3 = aPoints(n3);" EOL " } " EOL EOL " // Takes the polygon associated to an edge." EOL " aExpEdge.Init(aFace,TopAbs_EDGE);" EOL " TopoDS_Edge aEdge;" EOL " // for example,working with the first edge:" EOL " if(aExpEdge.More())" EOL " aEdge = TopoDS::Edge(aExpEdge.Current());" EOL EOL " if(!aEdge.IsNull()) // if this edge is not NULL" EOL " {" EOL " // takes the polygon associated to the edge aEdge:" EOL " Handle_Poly_PolygonOnTriangulation aPol = " EOL " BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location());" EOL EOL " if(!aPol.IsNull()) // if this polygon is not NULL" EOL " // takes the array of nodes for this polygon" EOL " // (indexes in the array of nodes for triangulation of theFace):" EOL " const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes();" EOL " }" EOL " }" EOL "}" EOL EOL "//==================================================" EOL EOL ; aText += " Result with deflection = "; aText += TCollection_AsciiString(aDeflection); aText += " :" EOL; GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText); // setResultText(aText.ToCString()); //========================================================================== BRepTools::Clean(aShape); BRepMesh::Mesh(aShape,aDeflection); BRep_Builder aBuilder,aBuild1,aBuild2; TopoDS_Compound aCompound,aComp1,aComp2; aBuilder.MakeCompound(aCompound); aBuild1.MakeCompound(aComp1); aBuild2.MakeCompound(aComp2); TopTools_SequenceOfShape aVertices; Standard_Integer aCount = 0; Standard_Integer aNumOfNodes = 0; Standard_Integer aNumOfTriangles = 0; Handle_AIS_InteractiveObject aShowEdge,aShowFace,aShowShape; TopExp_Explorer aExpFace,aExpEdge; for(aExpFace.Init(aShape,TopAbs_FACE);aExpFace.More();aExpFace.Next()) { aCount++; TopoDS_Face aFace = TopoDS::Face(aExpFace.Current()); TopLoc_Location aLocation; Handle_Poly_Triangulation aTr = BRep_Tool::Triangulation(aFace,aLocation); if(!aTr.IsNull()) { const TColgp_Array1OfPnt& aNodes = aTr->Nodes(); aNumOfNodes += aTr->NbNodes(); Standard_Integer aLower = aNodes.Lower(); Standard_Integer anUpper = aNodes.Upper(); const Poly_Array1OfTriangle& triangles = aTr->Triangles(); aNumOfTriangles += aTr->NbTriangles(); if(aCount == aNumOfFace) { Standard_Integer aNbOfNodesOfFace = aTr->NbNodes(); Standard_Integer aNbOfTrianglesOfFace = aTr->NbTriangles(); aExpEdge.Init(aFace,TopAbs_EDGE); TopoDS_Edge aEdge; for( Standard_Integer i = 0; aExpEdge.More() && i < aNumOfEdge ; aExpEdge.Next(), i++) aEdge = TopoDS::Edge(aExpEdge.Current()); if(!aEdge.IsNull()) { Handle_Poly_PolygonOnTriangulation aPol = BRep_Tool::PolygonOnTriangulation(aEdge,aTr,aEdge.Location()); if(!aPol.IsNull()) { const TColStd_Array1OfInteger& aNodesOfPol = aPol->Nodes(); Standard_Integer aNbOfNodesOfEdge = aPol->NbNodes(); aText += "Number of nodes of the edge = "; aText += TCollection_AsciiString(aNbOfNodesOfEdge) + EOL; aText += "Number of nodes of the face = "; aText += TCollection_AsciiString(aNbOfNodesOfFace) + EOL; aText += "Number of triangles of the face = "; aText += TCollection_AsciiString(aNbOfTrianglesOfFace) + EOL; GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText); // setResultText(aText.ToCString()); Standard_Integer aLower = aNodesOfPol.Lower(), anUpper = aNodesOfPol.Upper(); for( int i = aLower; i < anUpper ; i++) { gp_Pnt aPnt1 = aNodes(aNodesOfPol(i)).Transformed(aLocation); gp_Pnt aPnt2 = aNodes(aNodesOfPol(i+1)).Transformed(aLocation); TopoDS_Vertex aVertex1 = BRepBuilderAPI_MakeVertex (aPnt1); TopoDS_Vertex aVertex2 = BRepBuilderAPI_MakeVertex (aPnt2); if(!aVertex1.IsNull() && !aVertex2.IsNull() && // if vertices are "alive" !BRep_Tool::Pnt(aVertex1).IsEqual( BRep_Tool::Pnt(aVertex2),Precision::Confusion())) // if they are different { aEdge = BRepBuilderAPI_MakeEdge (aVertex1,aVertex2); aBuild2.Add(aComp2,aVertex1); if(!aEdge.IsNull()) aBuild2.Add(aComp2,aEdge); if(i == anUpper-1) aBuild2.Add(aComp2,aVertex2); } } getAISContext()->EraseAll(); aShowShape = drawShape(aShape); if(WAIT_A_SECOND) return; aShowEdge = drawShape(aComp2,Quantity_NOC_GREEN); getAISContext()->Erase(aShowShape); if(WAIT_A_SECOND) return; } } } TopTools_DataMapOfIntegerShape aEdges; TopTools_SequenceOfShape aVertices; for( Standard_Integer i = 1; i < aNodes.Length()+1; i++) { gp_Pnt aPnt = aNodes(i).Transformed(aLocation); TopoDS_Vertex aVertex = BRepBuilderAPI_MakeVertex(aPnt); if(!aVertex.IsNull()) { aBuilder.Add(aCompound,aVertex); if(aCount == aNumOfFace ) aBuild1.Add(aComp1,aVertex); aVertices.Append(aVertex); } } Standard_Integer nnn = aTr->NbTriangles(); Standard_Integer nt,n1,n2,n3; for( nt = 1 ; nt < nnn+1 ; nt++) { triangles(nt).Get(n1,n2,n3); Standard_Integer key[3]; TopoDS_Vertex aV1,aV2; key[0] = _key(n1, n2); if(!aEdges.IsBound(key[0])) { aV1 = TopoDS::Vertex(aVertices(n1)); aV2 = TopoDS::Vertex(aVertices(n2)); if(!aV1.IsNull() && !aV2.IsNull() && !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion())) { TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2); if(!aEdge.IsNull()) { aEdges.Bind(key[0], aEdge); aBuilder.Add(aCompound,aEdges(key[0])); if(aCount == aNumOfFace) aBuild1.Add(aComp1,aEdges(key[0])); } } } key[1] = _key(n2,n3); if(!aEdges.IsBound(key[1])) { aV1 = TopoDS::Vertex(aVertices(n2)); aV2 = TopoDS::Vertex(aVertices(n3)); if(!aV1.IsNull() && !aV2.IsNull() && !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion())) { TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2); if(!aEdge.IsNull()) { aEdges.Bind(key[1],aEdge); aBuilder.Add(aCompound,aEdges(key[1])); if(aCount == aNumOfFace) aBuild1.Add(aComp1,aEdges(key[1])); } } } key[2] = _key(n3,n1); if(!aEdges.IsBound(key[2])) { aV1 = TopoDS::Vertex(aVertices(n3)); aV2 = TopoDS::Vertex(aVertices(n1)); if(!aV1.IsNull() && !aV2.IsNull() && !BRep_Tool::Pnt(aV1).IsEqual(BRep_Tool::Pnt(aV2),Precision::Confusion())) { TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge (aV1,aV2); if(!aEdge.IsNull()) { aEdges.Bind(key[2],aEdge); aBuilder.Add(aCompound,aEdges(key[2])); if(aCount == aNumOfFace) aBuild1.Add(aComp1,aEdges(key[2])); } } } } if(aCount == aNumOfFace) { aShowFace = drawShape(aComp1,Quantity_NOC_GREEN); getAISContext()->Erase(aShowEdge); } } else { aText += "Can't compute a triangulation on face "; aText += TCollection_AsciiString(aCount) + EOL; GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText); // setResultText(aText.ToCString()); } } aText += "Number of nodes of the shape = "; aText += TCollection_AsciiString(aNumOfNodes) + EOL; aText += "Number of triangles of the shape = "; aText += TCollection_AsciiString(aNumOfTriangles) + EOL EOL; GetDocument()->PocessTextInDialog("Compute the triangulation on a shape", aText); // setResultText(aText.ToCString()); if(WAIT_A_SECOND) return; drawShape(aCompound,Quantity_NOC_GREEN); getAISContext()->Erase(aShowFace); }