// Returns the wing profile lower and upper wire fused TopoDS_Wire CCPACSWingProfile::GetSplitWire() { Update(); // rebuild closed wire BRepBuilderAPI_MakeWire closedWireBuilder; closedWireBuilder.Add(profileAlgo->GetLowerWire()); closedWireBuilder.Add(profileAlgo->GetUpperWire()); if (!profileAlgo->GetTrailingEdge().IsNull()) { closedWireBuilder.Add(profileAlgo->GetTrailingEdge()); } closedWireBuilder.Build(); if (!closedWireBuilder.IsDone()) { throw CTiglError("Error creating closed wing profile"); } return closedWireBuilder.Wire(); }
//======================================================================= //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; }
//======================================================================= //function : Execute //purpose : //======================================================================= Standard_Integer GEOMImpl_ChamferDriver::Execute(TFunction_Logbook& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); GEOMImpl_IChamfer aCI (aFunction); Standard_Integer aType = aFunction->GetType(); TopoDS_Shape aShape; Handle(GEOM_Function) aRefShape = aCI.GetShape(); TopoDS_Shape aShapeBase = aRefShape->GetValue(); if (aType == CHAMFER_SHAPE_EDGES_2D) { BRepFilletAPI_MakeFillet2d fill; TopoDS_Face aFace; Standard_Boolean aWireFlag = Standard_False; if (aShapeBase.ShapeType() == TopAbs_FACE) aFace = TopoDS::Face(aShapeBase); else if (aShapeBase.ShapeType() == TopAbs_WIRE) { TopoDS_Wire aWire = TopoDS::Wire(aShapeBase); BRepBuilderAPI_MakeFace aMF(aWire); aMF.Build(); if (!aMF.IsDone()) { StdFail_NotDone::Raise("Cannot build initial face from given wire"); } aFace = aMF.Face(); aWireFlag = Standard_True; } else StdFail_NotDone::Raise("Base shape is neither a face or a wire !"); fill.Init(aFace); double aD1_2D = aCI.GetD1(); double aD2_2D = aCI.GetD2(); TopoDS_Shape aShapeFace1, aShapeFace2; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.Get2DEdge1(), aShapeFace1) && GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.Get2DEdge2(), aShapeFace2)) { fill.AddChamfer(TopoDS::Edge(aShapeFace1), TopoDS::Edge(aShapeFace2), aD1_2D, aD2_2D); } else StdFail_NotDone::Raise("Cannot get 2d egde from sub-shape index!"); fill.Build(); if (!fill.IsDone()) { StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters"); } if (aWireFlag) { BRepBuilderAPI_MakeWire MW; TopExp_Explorer exp (fill.Shape(), TopAbs_EDGE); for (; exp.More(); exp.Next()) MW.Add(TopoDS::Edge(exp.Current())); MW.Build(); if (!MW.IsDone()) StdFail_NotDone::Raise("Resulting wire cannot be built"); aShape = MW.Shape(); } else aShape = fill.Shape(); } else { // Check the shape type. It have to be shell // or solid, or compsolid, or compound of these shapes. if (!isGoodForChamfer(aShapeBase)) { StdFail_NotDone::Raise ("Wrong shape. Must be shell or solid, or compsolid or compound of these shapes"); } BRepFilletAPI_MakeChamfer fill (aShapeBase); if (aType == CHAMFER_SHAPE_ALL) { // symmetric chamfer on all edges double aD = aCI.GetD(); TopTools_IndexedDataMapOfShapeListOfShape M; GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); for (int i = 1; i <= M.Extent(); i++) { TopoDS_Edge E = TopoDS::Edge(M.FindKey(i)); TopoDS_Face F = TopoDS::Face(M.FindFromIndex(i).First()); if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E) && M.FindFromIndex(i).Extent() == 2) fill.Add(aD, E, F); } }else if (aType == CHAMFER_SHAPE_EDGE || aType == CHAMFER_SHAPE_EDGE_AD) { // chamfer on edges, common to two faces, with D1 on the first face TopoDS_Shape aFace1, aFace2; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace1(), aFace1) && GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace2(), aFace2)) { TopoDS_Face F = TopoDS::Face(aFace1); // fill map of edges of the second face TopTools_MapOfShape aMap; TopExp_Explorer Exp2 (aFace2, TopAbs_EDGE); for (; Exp2.More(); Exp2.Next()) { aMap.Add(Exp2.Current()); } // find edges of the first face, common with the second face TopExp_Explorer Exp (aFace1, TopAbs_EDGE); for (; Exp.More(); Exp.Next()) { if (aMap.Contains(Exp.Current())) { TopoDS_Edge E = TopoDS::Edge(Exp.Current()); if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E)) { if ( aType == CHAMFER_SHAPE_EDGE ) { double aD1 = aCI.GetD1(); double aD2 = aCI.GetD2(); fill.Add(aD1, aD2, E, F); } else { double aD = aCI.GetD(); double anAngle = aCI.GetAngle(); if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) ) fill.AddDA(aD, anAngle, E, F); } } } } } } else if (aType == CHAMFER_SHAPE_FACES || aType == CHAMFER_SHAPE_FACES_AD) { // chamfer on all edges of the selected faces, with D1 on the selected face // (on first selected face, if the edge belongs to two selected faces) int aLen = aCI.GetLength(); int ind = 1; TopTools_MapOfShape aMap; TopTools_IndexedDataMapOfShapeListOfShape M; GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); for (; ind <= aLen; ind++) { TopoDS_Shape aShapeFace; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetFace(ind), aShapeFace)) { TopoDS_Face F = TopoDS::Face(aShapeFace); TopExp_Explorer Exp (F, TopAbs_EDGE); for (; Exp.More(); Exp.Next()) { if (!aMap.Contains(Exp.Current())) { TopoDS_Edge E = TopoDS::Edge(Exp.Current()); if (!BRepTools::IsReallyClosed(E, F) && !BRep_Tool::Degenerated(E) && M.FindFromKey(E).Extent() == 2) if (aType == CHAMFER_SHAPE_FACES) { double aD1 = aCI.GetD1(); double aD2 = aCI.GetD2(); fill.Add(aD1, aD2, E, F); } else { double aD = aCI.GetD(); double anAngle = aCI.GetAngle(); if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) ) fill.AddDA(aD, anAngle, E, F); } } } } } } else if (aType == CHAMFER_SHAPE_EDGES || aType == CHAMFER_SHAPE_EDGES_AD) { // chamfer on selected edges with lenght param D1 & D2. int aLen = aCI.GetLength(); int ind = 1; TopTools_MapOfShape aMap; TopTools_IndexedDataMapOfShapeListOfShape M; GEOMImpl_Block6Explorer::MapShapesAndAncestors(aShapeBase, TopAbs_EDGE, TopAbs_FACE, M); for (; ind <= aLen; ind++) { TopoDS_Shape aShapeEdge; if (GEOMImpl_ILocalOperations::GetSubShape(aShapeBase, aCI.GetEdge(ind), aShapeEdge)) { TopoDS_Edge E = TopoDS::Edge(aShapeEdge); const TopTools_ListOfShape& aFacesList = M.FindFromKey(E); TopoDS_Face F = TopoDS::Face( aFacesList.First() ); if (aType == CHAMFER_SHAPE_EDGES) { double aD1 = aCI.GetD1(); double aD2 = aCI.GetD2(); fill.Add(aD1, aD2, E, F); } else { double aD = aCI.GetD(); double anAngle = aCI.GetAngle(); if ( (anAngle > 0) && (anAngle < (Standard_PI/2)) ) fill.AddDA(aD, anAngle, E, F); } } } } else { } fill.Build(); if (!fill.IsDone()) { StdFail_NotDone::Raise("Chamfer can not be computed on the given shape with the given parameters"); } aShape = fill.Shape(); } if (aShape.IsNull()) return 0; // Check shape validity BRepCheck_Analyzer ana (aShape, false); if (!ana.IsValid()) { // 08.07.2008 added by skl during fixing bug 19761 from Mantis ShapeFix_ShapeTolerance aSFT; aSFT.LimitTolerance(aShape, Precision::Confusion(), Precision::Confusion(), TopAbs_SHAPE); Handle(ShapeFix_Shape) aSfs = new ShapeFix_Shape(aShape); aSfs->Perform(); aShape = aSfs->Shape(); // fix SameParameter flag BRepLib::SameParameter(aShape, 1.E-5, Standard_True); ana.Init(aShape); if (!ana.IsValid()) { Standard_CString anErrStr("Chamfer algorithm has produced an invalid shape result"); #ifdef THROW_ON_INVALID_SH Standard_ConstructionError::Raise(anErrStr); #else MESSAGE(anErrStr); //further processing can be performed here //... //in case of failure of automatic treatment //mark the corresponding GEOM_Object as problematic TDF_Label aLabel = aFunction->GetOwnerEntry(); if (!aLabel.IsRoot()) { Handle(GEOM_Object) aMainObj = GEOM_Object::GetObject(aLabel); if (!aMainObj.IsNull()) aMainObj->SetDirty(Standard_True); } #endif } } aFunction->SetValue(aShape); log.SetTouched(Label()); return 1; }