X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_ShapeDriver.cxx;h=71229e06c1dc8341ce357d160917df42dadf890b;hb=81de8c6b1111574ee1afba1b27b0db5a8f0059c4;hp=57f35386283519508d509861ff942fb2fecce7b0;hpb=3592a4861951f229ad7efdae552f37bfbcc026cc;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx index 57f353862..71229e06c 100644 --- a/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_ShapeDriver.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -22,14 +22,18 @@ #include +#include #include #include +#include #include #include #include #include #include +#include +#include // OCCT Includes #include @@ -42,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -56,6 +61,8 @@ #include #include +#include + #include #include #include @@ -68,6 +75,8 @@ #include #include +#include +#include #include #include @@ -76,12 +85,14 @@ #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -95,6 +106,279 @@ #include #include +#include +#include + +#include + +/** + * \brief This static function converts the list of shapes into an array + * of their IDs. If the input list is empty, null handle will be returned. + * this method doesn't check if a shape presents in theIndices map. + * + * \param theListOfShapes the list of shapes. + * \param theIndices the indexed map of shapes. + * \return the array of shape IDs. + */ +static Handle(TColStd_HArray1OfInteger) GetShapeIDs + (const TopTools_ListOfShape &theListOfShapes, + const TopTools_IndexedMapOfShape &theIndices) +{ + Handle(TColStd_HArray1OfInteger) aResult; + + if (!theListOfShapes.IsEmpty()) { + const Standard_Integer aNbShapes = theListOfShapes.Extent(); + TopTools_ListIteratorOfListOfShape anIter(theListOfShapes); + Standard_Integer i; + + aResult = new TColStd_HArray1OfInteger(1, aNbShapes); + + for (i = 1; anIter.More(); anIter.Next(), ++i) { + const TopoDS_Shape &aShape = anIter.Value(); + const Standard_Integer anIndex = theIndices.FindIndex(aShape); + + aResult->SetValue(i, anIndex); + } + } + + return aResult; +} + +namespace +{ + // check that compound includes only shapes of expected type + bool checkCompound( TopoDS_Shape& c, TopAbs_ShapeEnum t ) + { + TopoDS_Iterator it( c, Standard_True, Standard_True ); + + // empty compound is OK only if we explicitly create a compound of shapes + bool result = true; + + // => if expected type is TopAbs_SHAPE, we allow compound consisting of any shapes, this above check is enough + // => otherwise we have to check compound's content + // => compound sometimes can contain enclosed compound(s), we process them recursively and rebuild initial compound + + if ( t != TopAbs_SHAPE ) { + result = it.More(); + std::list compounds, shapes; + compounds.push_back( c ); + while ( !compounds.empty() && result ) { + // check that compound contains only shapes of expected type + TopoDS_Shape cc = compounds.front(); + compounds.pop_front(); + it.Initialize( cc, Standard_True, Standard_True ); + for ( ; it.More() && result; it.Next() ) { + TopAbs_ShapeEnum tt = it.Value().ShapeType(); + if ( tt == TopAbs_COMPOUND || tt == TopAbs_COMPSOLID ) { + compounds.push_back( it.Value() ); + continue; + } + shapes.push_back( it.Value() ); + result = tt == t; + } + } + if ( result ) { + if ( shapes.empty() ) { + result = false; + } + else if ( shapes.size() == 1 ) { + c = shapes.front(); + } + else { + BRep_Builder b; + TopoDS_Compound newc; + b.MakeCompound( newc ); + std::list ::const_iterator sit; + for ( sit = shapes.begin(); sit != shapes.end(); ++sit ) + b.Add( newc, *sit ); + c = newc; + } + } + } + + return result; + } + + /** + * This function adds faces from the input shape into the list of faces. If + * the input shape is a face, it is added itself. If it is a shell, its + * sub-shapes (faces) are added. If it is a compound, its sub-shapes + * (faces or shells) are added in the list. For null shapes and for other + * types of shapes an exception is thrown. + * + * @param theShape the shape to be added. Either face or shell or a compound + * of faces and/or shells. + * @param theListFaces the list of faces that is modified on output. + * @param theMapFence the map that protects from adding the same faces in + * the list. + */ + void addFaces(const TopoDS_Shape &theShape, + TopTools_ListOfShape &theListFaces, + TopTools_MapOfShape &theMapFence) + { + if (theShape.IsNull()) { + Standard_NullObject::Raise("Face for shell construction is null"); + } + + // Append the shape is the mapFence + if (theMapFence.Add(theShape)) { + // Shape type + const TopAbs_ShapeEnum aType = theShape.ShapeType(); + + if (aType == TopAbs_FACE) { + theListFaces.Append(theShape); + } else if (aType == TopAbs_SHELL || aType == TopAbs_COMPOUND) { + TopoDS_Iterator anIter(theShape); + + for (; anIter.More(); anIter.Next()) { + // Add sub-shapes: faces for shell or faces/shells for compound. + const TopoDS_Shape &aSubShape = anIter.Value(); + + addFaces(aSubShape, theListFaces, theMapFence); + } + } else { + Standard_TypeMismatch::Raise + ("Shape for shell construction is neither a shell nor a face"); + } + } + } + + /** + * This function constructs a shell or a compound of shells + * from a set of faces and/or shells. + * + * @param theShapes is a set of faces, shells and/or + * compounds of faces/shells. + * @return a shell or a compound of shells. + */ + TopoDS_Shape makeShellFromFaces + (const Handle(TColStd_HSequenceOfTransient) &theShapes) + { + const Standard_Integer aNbShapes = theShapes->Length(); + Standard_Integer i; + TopTools_ListOfShape aListFaces; + TopTools_MapOfShape aMapFence; + BRep_Builder aBuilder; + + // Fill the list of unique faces + for (i = 1; i <= aNbShapes; ++i) { + // Function + const Handle(GEOM_Function) aRefShape = + Handle(GEOM_Function)::DownCast(theShapes->Value(i)); + + if (aRefShape.IsNull()) { + Standard_NullObject::Raise("Face for shell construction is null"); + } + + // Shape + const TopoDS_Shape aShape = aRefShape->GetValue(); + + addFaces(aShape, aListFaces, aMapFence); + } + + // Perform computation of shells. + TopTools_ListOfShape aListShells; + TopTools_ListIteratorOfListOfShape anIter; + + while (!aListFaces.IsEmpty()) { + // Perform sewing + BRepBuilderAPI_Sewing aSewing(Precision::Confusion()*10.0); + + for (anIter.Initialize(aListFaces); anIter.More(); anIter.Next()) { + aSewing.Add(anIter.Value()); + } + + aSewing.Perform(); + + // Fill list of shells. + const TopoDS_Shape &aSewed = aSewing.SewedShape(); + TopExp_Explorer anExp(aSewed, TopAbs_SHELL); + Standard_Boolean isNewShells = Standard_False; + + // Append shells + for (; anExp.More(); anExp.Next()) { + aListShells.Append(anExp.Current()); + isNewShells = Standard_True; + } + + // Append single faces. + anExp.Init(aSewed, TopAbs_FACE, TopAbs_SHELL); + + for (; anExp.More(); anExp.Next()) { + TopoDS_Shell aShell; + + aBuilder.MakeShell(aShell); + aBuilder.Add(aShell, anExp.Current()); + aListShells.Append(aShell); + isNewShells = Standard_True; + } + + if (!isNewShells) { + // There are no more shell can be obtained. Break the loop. + break; + } + + // Remove faces that are in the result from the list. + TopTools_IndexedMapOfShape aMapFaces; + + TopExp::MapShapes(aSewed, TopAbs_FACE, aMapFaces); + + // Add deleted faces to the map + const Standard_Integer aNbDelFaces = aSewing.NbDeletedFaces(); + + for (i = 1; i <= aNbDelFaces; ++i) { + aMapFaces.Add(aSewing.DeletedFace(i)); + } + + for (anIter.Initialize(aListFaces); anIter.More();) { + const TopoDS_Shape &aFace = anIter.Value(); + Standard_Boolean isFaceUsed = Standard_False; + + if (aMapFaces.Contains(aFace) || aSewing.IsModified(aFace)) { + // Remove face from the list. + aListFaces.Remove(anIter); + } else { + // Go to the next face. + anIter.Next(); + } + } + } + + // If there are faces not used in shells create a shell for each face. + for (anIter.Initialize(aListFaces); anIter.More(); anIter.Next()) { + TopoDS_Shell aShell; + + aBuilder.MakeShell(aShell); + aBuilder.Add(aShell, anIter.Value()); + aListShells.Append(aShell); + } + + // Construct the result that can be either a shell or a compound of shells + TopoDS_Shape aResult; + + if (!aListShells.IsEmpty()) { + if (aListShells.Extent() == 1) { + aResult = aListShells.First(); + } else { + // There are more then one shell. + TopoDS_Compound aCompound; + + aBuilder.MakeCompound(aCompound); + + for (anIter.Initialize(aListShells); anIter.More(); anIter.Next()) { + aBuilder.Add(aCompound, anIter.Value()); + } + + aResult = aCompound; + } + } + + return aResult; + } + + // End of namespace +} + //modified by NIZNHY-PKV Wed Dec 28 13:48:20 2011f //static // void KeepEdgesOrder(const Handle(TopTools_HSequenceOfShape)& aEdges, @@ -124,7 +408,7 @@ GEOMImpl_ShapeDriver::GEOMImpl_ShapeDriver() //function : Execute //purpose : //======================================================================= -Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const +Standard_Integer GEOMImpl_ShapeDriver::Execute(Handle(TFunction_Logbook)& log) const { if (Label().IsNull()) return 0; Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label()); @@ -134,11 +418,16 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const TopoDS_Shape aShape; TCollection_AsciiString aWarning; + + // this is an exact type of expected shape, or shape in a compound if compound is allowed as a result (see below) TopAbs_ShapeEnum anExpectedType = TopAbs_SHAPE; + // this should be true if result can be a compound of shapes of strict type (see above) + bool allowCompound = false; BRep_Builder B; if (aType == WIRE_EDGES) { + // result may be only a single wire anExpectedType = TopAbs_WIRE; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); @@ -150,7 +439,9 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = MakeWireFromEdges(aShapes, aTolerance); } else if (aType == FACE_WIRE) { + // result may be a face or a compound of faces anExpectedType = TopAbs_FACE; + allowCompound = true; Handle(GEOM_Function) aRefBase = aCI.GetBase(); TopoDS_Shape aShapeBase = aRefBase->GetValue(); @@ -167,7 +458,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const Standard_NullObject::Raise ("Shape for face construction is not closed"); } - else if (aShapeBase.ShapeType() == TopAbs_EDGE && aShapeBase.Closed()) { + else if (aShapeBase.ShapeType() == TopAbs_EDGE && BRep_Tool::IsClosed(aShapeBase)) { BRepBuilderAPI_MakeWire MW; MW.Add(TopoDS::Edge(aShapeBase)); if (!MW.IsDone()) { @@ -185,7 +476,9 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } } else if (aType == FACE_WIRES) { + // result may be a face or a compound of faces anExpectedType = TopAbs_FACE; + allowCompound = true; // Try to build a face from a set of wires and edges int ind; @@ -199,6 +492,7 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const // 1. Extract all edges from the given arguments TopTools_MapOfShape aMapEdges; Handle(TopTools_HSequenceOfShape) aSeqEdgesIn = new TopTools_HSequenceOfShape; + TColStd_IndexedDataMapOfTransientTransient aMapTShapes; for (ind = 1; ind <= nbshapes; ind++) { Handle(GEOM_Function) aRefSh_i = Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); @@ -207,11 +501,20 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const TopExp_Explorer anExpE_i (aSh_i, TopAbs_EDGE); for (; anExpE_i.More(); anExpE_i.Next()) { if (aMapEdges.Add(anExpE_i.Current())) { - aSeqEdgesIn->Append(anExpE_i.Current()); + // Copy the original shape. + TopoDS_Shape aShapeCopy; + + TNaming_CopyShape::CopyTool + (anExpE_i.Current(), aMapTShapes, aShapeCopy); + aSeqEdgesIn->Append(aShapeCopy); } } } + if (aSeqEdgesIn->IsEmpty()) { + Standard_ConstructionError::Raise("No edges given"); + } + // 2. Connect edges to wires of maximum length Handle(TopTools_HSequenceOfShape) aSeqWiresOut; ShapeAnalysis_FreeBounds::ConnectEdgesToWires(aSeqEdgesIn, Precision::Confusion(), @@ -302,96 +605,61 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = C; } } - else if (aType == SHELL_FACES) { - anExpectedType = TopAbs_SHELL; + else if (aType == FACE_FROM_SURFACE) { + // result may be only a face + anExpectedType = TopAbs_FACE; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); - unsigned int ind, nbshapes = aShapes->Length(); - - // add faces - BRepBuilderAPI_Sewing aSewing (Precision::Confusion()*10.0); - for (ind = 1; ind <= nbshapes; ind++) { - Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); - TopoDS_Shape aShape_i = aRefShape->GetValue(); - if (aShape_i.IsNull()) { - Standard_NullObject::Raise("Face for shell construction is null"); - } - aSewing.Add(aShape_i); - } - - aSewing.Perform(); - - TopoDS_Shape sh = aSewing.SewedShape(); - - if (sh.ShapeType()==TopAbs_FACE && nbshapes==1) { - // case for creation of shell from one face - PAL12722 (skl 26.06.2006) - TopoDS_Shell ss; - B.MakeShell(ss); - B.Add(ss,sh); - aShape = ss; - } - else { - //TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL); - TopExp_Explorer exp (sh, TopAbs_SHELL); - Standard_Integer ish = 0; - for (; exp.More(); exp.Next()) { - aShape = exp.Current(); - ish++; - } - - if (ish != 1) { - // try the case of one face (Mantis issue 0021809) - TopExp_Explorer expF (sh, TopAbs_FACE); - Standard_Integer ifa = 0; - for (; expF.More(); expF.Next()) { - aShape = expF.Current(); - ifa++; - } - if (ifa == 1) { - TopoDS_Shell ss; - B.MakeShell(ss); - B.Add(ss,aShape); - aShape = ss; - } - else { - aShape = aSewing.SewedShape(); + if (aShapes.IsNull() == Standard_False) { + Standard_Integer aNbShapes = aShapes->Length(); + + if (aNbShapes == 2) { + Handle(GEOM_Function) aRefFace = + Handle(GEOM_Function)::DownCast(aShapes->Value(1)); + Handle(GEOM_Function) aRefWire = + Handle(GEOM_Function)::DownCast(aShapes->Value(2)); + + if (aRefFace.IsNull() == Standard_False && + aRefWire.IsNull() == Standard_False) { + TopoDS_Shape aShFace = aRefFace->GetValue(); + TopoDS_Shape aShWire = aRefWire->GetValue(); + + if (aShFace.IsNull() == Standard_False && + aShFace.ShapeType() == TopAbs_FACE && + aShWire.IsNull() == Standard_False && + aShWire.ShapeType() == TopAbs_WIRE) { + TopoDS_Face aFace = TopoDS::Face(aShFace); + TopoDS_Wire aWire = TopoDS::Wire(aShWire); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + BRepBuilderAPI_MakeFace aMkFace(aSurf, aWire); + + if (aMkFace.IsDone()) { + aShape = aMkFace.Shape(); + } + } } } } - } - else if (aType == SOLID_SHELL) { - anExpectedType = TopAbs_SOLID; - - Handle(GEOM_Function) aRefShell = aCI.GetBase(); - TopoDS_Shape aShapeShell = aRefShell->GetValue(); - if (!aShapeShell.IsNull() && aShapeShell.ShapeType() == TopAbs_COMPOUND) { - TopoDS_Iterator It (aShapeShell, Standard_True, Standard_True); - if (It.More()) aShapeShell = It.Value(); - } - if (aShapeShell.IsNull() || aShapeShell.ShapeType() != TopAbs_SHELL) { - Standard_NullObject::Raise("Shape for solid construction is null or not a shell"); - } + else if (aType == SHELL_FACES) { + // result may be only a shell or a compound of shells + anExpectedType = TopAbs_SHELL; + allowCompound = true; - BRepCheck_Shell chkShell(TopoDS::Shell(aShapeShell)); - if (chkShell.Closed() == BRepCheck_NotClosed) return 0; + Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); - TopoDS_Solid Sol; - B.MakeSolid(Sol); - B.Add(Sol, aShapeShell); - BRepClass3d_SolidClassifier SC (Sol); - SC.PerformInfinitePoint(Precision::Confusion()); - if (SC.State() == TopAbs_IN) { - B.MakeSolid(Sol); - B.Add(Sol, aShapeShell.Reversed()); + if (aShapes.IsNull()) { + Standard_NullObject::Raise("Argument Shapes is null"); } - aShape = Sol; - + // Compute a shell or a compound of shells. + aShape = makeShellFromFaces(aShapes); } else if (aType == SOLID_SHELLS) { + // result may be only a solid or a compound of solids anExpectedType = TopAbs_SOLID; + allowCompound = true; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -407,9 +675,18 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const } if (aShapeShell.ShapeType() == TopAbs_COMPOUND) { TopoDS_Iterator It (aShapeShell, Standard_True, Standard_True); - if (It.More()) aShapeShell = It.Value(); + for (; It.More(); It.Next()) { + TopoDS_Shape aSubShape = It.Value(); + if (aSubShape.ShapeType() == TopAbs_SHELL) { + aMkSolid.Add(TopoDS::Shell(aSubShape)); + ish++; + } + else + Standard_TypeMismatch::Raise + ("Shape for solid construction is neither a shell nor a compound of shells"); + } } - if (aShapeShell.ShapeType() == TopAbs_SHELL) { + else if (aShapeShell.ShapeType() == TopAbs_SHELL) { aMkSolid.Add(TopoDS::Shell(aShapeShell)); ish++; } @@ -425,7 +702,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = Sol; } else if (aType == COMPOUND_SHAPES) { - anExpectedType = TopAbs_COMPOUND; + // result may be only a compound of any shapes + allowCompound = true; Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); unsigned int ind, nbshapes = aShapes->Length(); @@ -445,31 +723,8 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = C; } - /* - else if (aType == REVERSE_ORIENTATION) { - Handle(GEOM_Function) aRefShape = aCI.GetBase(); - TopoDS_Shape aShape_i = aRefShape->GetValue(); - if (aShape_i.IsNull()) { - Standard_NullObject::Raise("Shape for reverse is null"); - } - - BRepBuilderAPI_Copy Copy(aShape_i); - if( Copy.IsDone() ) { - TopoDS_Shape tds = Copy.Shape(); - if( tds.IsNull() ) { - Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape"); - } - - if( tds.Orientation() == TopAbs_FORWARD) - tds.Orientation(TopAbs_REVERSED); - else - tds.Orientation(TopAbs_FORWARD); - - aShape = tds; - } - } - */ else if (aType == EDGE_WIRE) { + // result may be only an edge anExpectedType = TopAbs_EDGE; Handle(GEOM_Function) aRefBase = aCI.GetBase(); @@ -480,7 +735,47 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = MakeEdgeFromWire(aWire, LinTol, AngTol); } + else if (aType == SOLID_FACES) { + // result may be only a solid or a compound of solids + anExpectedType = TopAbs_SOLID; + allowCompound = true; + + Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes(); + unsigned int ind, nbshapes = aShapes->Length(); + + // add faces + TopTools_ListOfShape aLS; + for (ind = 1; ind <= nbshapes; ind++) { + Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind)); + TopoDS_Shape aShape_i = aRefShape->GetValue(); + if (aShape_i.IsNull()) { + Standard_NullObject::Raise("Shape for solid construction is null"); + } + if (aShape_i.ShapeType() == TopAbs_COMPOUND) { + TopoDS_Iterator It (aShape_i, Standard_True, Standard_True); + for (; It.More(); It.Next()) { + TopoDS_Shape aSubShape = It.Value(); + if (aSubShape.ShapeType() == TopAbs_FACE || aSubShape.ShapeType() == TopAbs_SHELL) + aLS.Append(aSubShape); + else + Standard_TypeMismatch::Raise + ("Shape for solid construction is neither a list of faces and/or shells " + "nor a compound of faces and/or shells"); + } + } + aLS.Append(aShape_i); + } + + BOPAlgo_MakerVolume aMV; + aMV.SetArguments(aLS); + aMV.SetIntersect(aCI.GetIsIntersect()); + aMV.Perform(); + if (aMV.HasErrors()) return 0; + + aShape = aMV.Shape(); + } else if (aType == EDGE_CURVE_LENGTH) { + // result may be only an edge anExpectedType = TopAbs_EDGE; GEOMImpl_IVector aVI (aFunction); @@ -556,7 +851,12 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const BRepBuilderAPI_MakeEdge aME (ReOrientedCurve, UFirst, aParam); if (aME.IsDone()) aShape = aME.Shape(); - } else if (aType == SHAPE_ISOLINE) { + } + else if (aType == SHAPE_ISOLINE) { + // result may be only an edge or compound of edges + anExpectedType = TopAbs_EDGE; + allowCompound = true; + GEOMImpl_IIsoline aII (aFunction); Handle(GEOM_Function) aRefFace = aII.GetFace(); TopoDS_Shape aShapeFace = aRefFace->GetValue(); @@ -583,13 +883,179 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const ("Shape for isoline construction is not a face"); } } + else if (aType == EDGE_UV) { + // result may be only an edge + anExpectedType = TopAbs_EDGE; + + GEOMImpl_IShapeExtend aSE (aFunction); + Handle(GEOM_Function) aRefEdge = aSE.GetShape(); + TopoDS_Shape aShapeEdge = aRefEdge->GetValue(); + + if (aShapeEdge.ShapeType() == TopAbs_EDGE) { + TopoDS_Edge anEdge = TopoDS::Edge(aShapeEdge); + + aShape = ExtendEdge(anEdge, aSE.GetUMin(), aSE.GetUMax()); + } + } + else if (aType == FACE_UV) { + // result may be only a face + anExpectedType = TopAbs_FACE; + + GEOMImpl_IShapeExtend aSE (aFunction); + Handle(GEOM_Function) aRefFace = aSE.GetShape(); + TopoDS_Shape aShapeFace = aRefFace->GetValue(); + + if (aShapeFace.ShapeType() == TopAbs_FACE) { + TopoDS_Face aFace = TopoDS::Face(aShapeFace); + + aFace.Orientation(TopAbs_FORWARD); + aShape = ExtendFace(aFace, aSE.GetUMin(), aSE.GetUMax(), + aSE.GetVMin(), aSE.GetVMax()); + } + } + else if (aType == SURFACE_FROM_FACE) { + // result may be only a face + anExpectedType = TopAbs_FACE; + + GEOMImpl_IShapeExtend aSE (aFunction); + Handle(GEOM_Function) aRefFace = aSE.GetShape(); + TopoDS_Shape aShapeFace = aRefFace->GetValue(); + + if (aShapeFace.ShapeType() == TopAbs_FACE) { + TopoDS_Face aFace = TopoDS::Face(aShapeFace); + Handle(Geom_Surface) aSurface = BRep_Tool::Surface(aFace); + + if (aSurface.IsNull() == Standard_False) { + Handle(Standard_Type) aType = aSurface->DynamicType(); + Standard_Real aU1; + Standard_Real aU2; + Standard_Real aV1; + Standard_Real aV2; + + // Get U, V bounds of the face. + aFace.Orientation(TopAbs_FORWARD); + ShapeAnalysis::GetFaceUVBounds(aFace, aU1, aU2, aV1, aV2); + + // Get the surface of original type + while (aType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { + Handle(Geom_RectangularTrimmedSurface) aTrSurface = + Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface); + + aSurface = aTrSurface->BasisSurface(); + aType = aSurface->DynamicType(); + } + + const Standard_Real aTol = BRep_Tool::Tolerance(aFace); + BRepBuilderAPI_MakeFace aMF(aSurface, aU1, aU2, aV1, aV2, aTol); + + if (aMF.IsDone()) { + aShape = aMF.Shape(); + } + } + } + } else if (aType == EXTRACTION) { + allowCompound = true; + + GEOMImpl_IExtract aCI(aFunction); + Handle(GEOM_Function) aRefShape = aCI.GetShape(); + TopoDS_Shape aShapeBase = aRefShape->GetValue(); + + if (aShapeBase.IsNull()) { + Standard_NullObject::Raise("Argument Shape is null"); + return 0; + } + + Handle(TColStd_HArray1OfInteger) anIDs = aCI.GetSubShapeIDs(); + TopTools_ListOfShape aListSubShapes; + TopTools_IndexedMapOfShape anIndices; + int i; + + TopExp::MapShapes(aShapeBase, anIndices); + + if (!anIDs.IsNull()) { + const int anUpperID = anIDs->Upper(); + const int aNbShapes = anIndices.Extent(); + + for (i = anIDs->Lower(); i <= anUpperID; ++i) { + const Standard_Integer anIndex = anIDs->Value(i); + + if (anIndex < 1 || anIndex > aNbShapes) { + TCollection_AsciiString aMsg(" Invalid index: "); + + aMsg += TCollection_AsciiString(anIndex); + StdFail_NotDone::Raise(aMsg.ToCString()); + return 0; + } + + const TopoDS_Shape &aSubShape = anIndices.FindKey(anIndex); + + aListSubShapes.Append(aSubShape); + } + } + + // Compute extraction. + GEOMAlgo_Extractor anExtractor; + + anExtractor.SetShape(aShapeBase); + anExtractor.SetShapesToRemove(aListSubShapes); + + anExtractor.Perform(); + + // Interpret results + Standard_Integer iErr = anExtractor.ErrorStatus(); + + // The detailed description of error codes is in GEOMAlgo_Extractor.cxx + if (iErr) { + TCollection_AsciiString aMsg(" iErr : "); + + aMsg += TCollection_AsciiString(iErr); + StdFail_NotDone::Raise(aMsg.ToCString()); + return 0; + } + + aShape = anExtractor.GetResult(); + + if (aShape.IsNull()) { + Standard_ConstructionError::Raise("Result of extraction is empty"); + } + + // Get statistics. + const TopTools_ListOfShape &aRemoved = anExtractor.GetRemoved(); + const TopTools_ListOfShape &aModified = anExtractor.GetModified(); + const TopTools_ListOfShape &aNew = anExtractor.GetNew(); + Handle(TColStd_HArray1OfInteger) aRemovedIDs = + GetShapeIDs(aRemoved, anIndices); + Handle(TColStd_HArray1OfInteger) aModifiedIDs = + GetShapeIDs(aModified, anIndices); + Handle(TColStd_HArray1OfInteger) aNewIDs; + + if (!aShape.IsNull()) { + // Get newly created sub-shapes + TopTools_IndexedMapOfShape aNewIndices; + + TopExp::MapShapes(aShape, aNewIndices); + aNewIDs = GetShapeIDs(aNew, aNewIndices); + } + + if (!aRemovedIDs.IsNull()) { + aCI.SetRemovedIDs(aRemovedIDs); + } + + if (!aModifiedIDs.IsNull()) { + aCI.SetModifiedIDs(aModifiedIDs); + } + + if (!aNewIDs.IsNull()) { + aCI.SetAddedIDs(aNewIDs); + } + } else { } if (aShape.IsNull()) return 0; // Check shape validity - BRepCheck_Analyzer ana (aShape, false); + BRepCheck_Analyzer ana (aShape, true); if (!ana.IsValid()) { //Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result"); // For Mantis issue 0021772: EDF 2336 GEOM: Non valid face created from two circles @@ -598,16 +1064,22 @@ Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const aShape = aSfs->Shape(); } - // Check if the result shape type is compatible with the expected. + // Check if the result shape is of expected type. const TopAbs_ShapeEnum aShType = aShape.ShapeType(); - if (anExpectedType != TopAbs_SHAPE && anExpectedType != aShType) { - Standard_ConstructionError::Raise("Result type check failed"); + bool ok = false; + if ( aShType == TopAbs_COMPOUND || aShType == TopAbs_COMPSOLID ) { + ok = allowCompound && checkCompound( aShape, anExpectedType ); + } + else { + ok = ( anExpectedType == TopAbs_SHAPE ) || ( aShType == anExpectedType ); } + if (!ok) + Standard_ConstructionError::Raise("Result type check failed"); aFunction->SetValue(aShape); - log.SetTouched(Label()); + log->SetTouched(Label()); if (!aWarning.IsEmpty()) Standard_Failure::Raise(aWarning.ToCString()); @@ -702,6 +1174,7 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, TColStd_SequenceOfReal TolSeq; GeomAbs_CurveType CurType; TopoDS_Vertex FirstVertex, LastVertex; + Standard_Real aPntShiftDist = 0.; BRepTools_WireExplorer wexp(theWire) ; for (; wexp.More(); wexp.Next()) @@ -738,11 +1211,13 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, { Standard_Boolean Done = Standard_False; Standard_Real NewFpar, NewLpar; - GeomAdaptor_Curve GAprevcurve(CurveSeq.Last()); + Handle(Geom_Geometry) aTrsfGeom = CurveSeq.Last()->Transformed + (LocSeq.Last().Location().Transformation()); + GeomAdaptor_Curve GAprevcurve(Handle(Geom_Curve)::DownCast(aTrsfGeom)); TopoDS_Vertex CurVertex = wexp.CurrentVertex(); TopoDS_Vertex CurFirstVer = TopExp::FirstVertex(anEdge); TopAbs_Orientation ConnectByOrigin = (CurVertex.IsSame(CurFirstVer))? TopAbs_FORWARD : TopAbs_REVERSED; - if (aCurve == CurveSeq.Last()) + if (aCurve == CurveSeq.Last() && aLoc.IsEqual(LocSeq.Last().Location())) { NewFpar = fpar; NewLpar = lpar; @@ -779,6 +1254,18 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, gp_Pnt P2 = ElCLib::Value(lpar, aLine); NewFpar = ElCLib::Parameter(PrevLine, P1); NewLpar = ElCLib::Parameter(PrevLine, P2); + + // Compute shift + if (ConnectByOrigin == TopAbs_FORWARD) { + gp_Pnt aNewP2 = ElCLib::Value(NewLpar, PrevLine); + + aPntShiftDist += P2.Distance(aNewP2); + } else { + gp_Pnt aNewP1 = ElCLib::Value(NewFpar, PrevLine); + + aPntShiftDist += P1.Distance(aNewP1); + } + if (NewLpar < NewFpar) { Standard_Real MemNewFpar = NewFpar; @@ -798,6 +1285,8 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, Abs(aCircle.Radius() - PrevCircle.Radius()) <= LinTol && aCircle.Axis().IsParallel(PrevCircle.Axis(), AngTol)) { + const Standard_Boolean isFwd = ConnectByOrigin == TopAbs_FORWARD; + if (aCircle.Axis().Direction() * PrevCircle.Axis().Direction() < 0.) { Standard_Real memfpar = fpar; @@ -809,6 +1298,18 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, gp_Pnt P2 = ElCLib::Value(lpar, aCircle); NewFpar = ElCLib::Parameter(PrevCircle, P1); NewLpar = ElCLib::Parameter(PrevCircle, P2); + + // Compute shift + if (isFwd) { + gp_Pnt aNewP2 = ElCLib::Value(NewLpar, PrevCircle); + + aPntShiftDist += P2.Distance(aNewP2); + } else { + gp_Pnt aNewP1 = ElCLib::Value(NewFpar, PrevCircle); + + aPntShiftDist += P1.Distance(aNewP1); + } + if (NewLpar < NewFpar) NewLpar += 2.*M_PI; //Standard_Real MemNewFpar = NewFpar, MemNewLpar = NewLpar; @@ -834,6 +1335,8 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, Abs(anEllipse.MinorRadius() - PrevEllipse.MinorRadius()) <= LinTol && anEllipse.Axis().IsParallel(PrevEllipse.Axis(), AngTol)) { + const Standard_Boolean isFwd = ConnectByOrigin == TopAbs_FORWARD; + if (anEllipse.Axis().Direction() * PrevEllipse.Axis().Direction() < 0.) { Standard_Real memfpar = fpar; @@ -845,6 +1348,18 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, gp_Pnt P2 = ElCLib::Value(lpar, anEllipse); NewFpar = ElCLib::Parameter(PrevEllipse, P1); NewLpar = ElCLib::Parameter(PrevEllipse, P2); + + // Compute shift + if (isFwd) { + gp_Pnt aNewP2 = ElCLib::Value(NewLpar, PrevEllipse); + + aPntShiftDist += P2.Distance(aNewP2); + } else { + gp_Pnt aNewP1 = ElCLib::Value(NewFpar, PrevEllipse); + + aPntShiftDist += P1.Distance(aNewP1); + } + if (NewLpar < NewFpar) NewLpar += 2.*M_PI; if (ConnectByOrigin == TopAbs_FORWARD) @@ -873,6 +1388,18 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, gp_Pnt P2 = ElCLib::Value(lpar, aHypr); NewFpar = ElCLib::Parameter(PrevHypr, P1); NewLpar = ElCLib::Parameter(PrevHypr, P2); + + // Compute shift + if (ConnectByOrigin == TopAbs_FORWARD) { + gp_Pnt aNewP2 = ElCLib::Value(NewLpar, PrevHypr); + + aPntShiftDist += P2.Distance(aNewP2); + } else { + gp_Pnt aNewP1 = ElCLib::Value(NewFpar, PrevHypr); + + aPntShiftDist += P1.Distance(aNewP1); + } + if (NewLpar < NewFpar) { Standard_Real MemNewFpar = NewFpar; @@ -897,6 +1424,18 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, gp_Pnt P2 = ElCLib::Value(lpar, aParab); NewFpar = ElCLib::Parameter(PrevParab, P1); NewLpar = ElCLib::Parameter(PrevParab, P2); + + // Compute shift + if (ConnectByOrigin == TopAbs_FORWARD) { + gp_Pnt aNewP2 = ElCLib::Value(NewLpar, PrevParab); + + aPntShiftDist += P2.Distance(aNewP2); + } else { + gp_Pnt aNewP1 = ElCLib::Value(NewFpar, PrevParab); + + aPntShiftDist += P1.Distance(aNewP1); + } + if (NewLpar < NewFpar) { Standard_Real MemNewFpar = NewFpar; @@ -926,14 +1465,15 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, LocSeq.Append(aLocShape); FparSeq.Append(fpar); LparSeq.Append(lpar); - TolSeq.Append(BRep_Tool::Tolerance(CurVertex)); + TolSeq.Append(aPntShiftDist + BRep_Tool::Tolerance(CurVertex)); + aPntShiftDist = 0.; CurType = aType; } } // end of else (CurveSeq.IsEmpty()) -> not first time } // end for (; wexp.More(); wexp.Next()) LastVertex = wexp.CurrentVertex(); - TolSeq.Append(BRep_Tool::Tolerance(LastVertex)); + TolSeq.Append(aPntShiftDist + BRep_Tool::Tolerance(LastVertex)); FirstVertex.Orientation(TopAbs_FORWARD); LastVertex.Orientation(TopAbs_REVERSED); @@ -1009,7 +1549,7 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, if (closed_flag) { // Check if closed curve is reordered. - Handle(Geom_Curve) aCurve = concatcurve->Value(concatcurve->Lower()); + Handle(Geom_BSplineCurve) aCurve = concatcurve->Value(concatcurve->Lower()); Standard_Real aFPar = aCurve->FirstParameter(); gp_Pnt aPFirst; gp_Pnt aPntVtx = BRep_Tool::Pnt(FirstVertex); @@ -1031,7 +1571,7 @@ TopoDS_Edge GEOMImpl_ShapeDriver::MakeEdgeFromWire(const TopoDS_Shape& aWire, const Standard_Real aTol = BRep_Tool::Tolerance(aVtx); if (aPFirst.IsEqual(aPnt, aTol)) { - // The coinsident vertex is found. + // The coincident vertex is found. FirstVertex = aVtx; LastVertex = aVtx; FirstVertex.Orientation(TopAbs_FORWARD); @@ -1185,6 +1725,150 @@ TopoDS_Shape GEOMImpl_ShapeDriver::MakeIsoline return aResult; } +//============================================================================= +/*! + * \brief Returns an extended edge. + */ +//============================================================================= + +TopoDS_Shape GEOMImpl_ShapeDriver::ExtendEdge + (const TopoDS_Edge &theEdge, + const Standard_Real theMin, + const Standard_Real theMax) const +{ + TopoDS_Shape aResult; + Standard_Real aF; + Standard_Real aL; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(theEdge, aF, aL); + const Standard_Real aTol = BRep_Tool::Tolerance(theEdge); + Standard_Real aRange2d = aL - aF; + + if (aCurve.IsNull() == Standard_False && aRange2d > aTol) { + Standard_Real aMin = aF + aRange2d*theMin; + Standard_Real aMax = aF + aRange2d*theMax; + + Handle(Standard_Type) aType = aCurve->DynamicType(); + + // Get the curve of original type + while (aType == STANDARD_TYPE(Geom_TrimmedCurve)) { + Handle(Geom_TrimmedCurve) aTrCurve = + Handle(Geom_TrimmedCurve)::DownCast(aCurve); + + aCurve = aTrCurve->BasisCurve(); + aType = aCurve->DynamicType(); + } + + if (aCurve->IsPeriodic()) { + // The curve is periodic. Check if a new range is less then a period. + if (aMax - aMin > aCurve->Period()) { + aMax = aMin + aCurve->Period(); + } + } else { + // The curve is not periodic. Check if aMin and aMax within bounds. + aMin = Max(aMin, aCurve->FirstParameter()); + aMax = Min(aMax, aCurve->LastParameter()); + } + + if (aMax - aMin > aTol) { + // Create a new edge. + BRepBuilderAPI_MakeEdge aME (aCurve, aMin, aMax); + + if (aME.IsDone()) { + aResult = aME.Shape(); + } + } + } + + return aResult; +} + +//============================================================================= +/*! + * \brief Returns an extended face. + */ +//============================================================================= + +TopoDS_Shape GEOMImpl_ShapeDriver::ExtendFace + (const TopoDS_Face &theFace, + const Standard_Real theUMin, + const Standard_Real theUMax, + const Standard_Real theVMin, + const Standard_Real theVMax) const +{ + TopoDS_Shape aResult; + Handle(Geom_Surface) aSurface = BRep_Tool::Surface(theFace); + const Standard_Real aTol = BRep_Tool::Tolerance(theFace); + Standard_Real aU1; + Standard_Real aU2; + Standard_Real aV1; + Standard_Real aV2; + + // Get U, V bounds of the face. + ShapeAnalysis::GetFaceUVBounds(theFace, aU1, aU2, aV1, aV2); + + const Standard_Real aURange = aU2 - aU1; + const Standard_Real aVRange = aV2 - aV1; + + if (aSurface.IsNull() == Standard_False && + aURange > aTol && aURange > aTol) { + Handle(Standard_Type) aType = aSurface->DynamicType(); + + // Get the surface of original type + while (aType == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { + Handle(Geom_RectangularTrimmedSurface) aTrSurface = + Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurface); + + aSurface = aTrSurface->BasisSurface(); + aType = aSurface->DynamicType(); + } + + Standard_Real aUMin = aU1 + aURange*theUMin; + Standard_Real aUMax = aU1 + aURange*theUMax; + Standard_Real aVMin = aV1 + aVRange*theVMin; + Standard_Real aVMax = aV1 + aVRange*theVMax; + + aSurface->Bounds(aU1, aU2, aV1, aV2); + + if (aSurface->IsUPeriodic()) { + // The surface is U-periodic. Check if a new U range is less + // then a period. + if (aUMax - aUMin > aSurface->UPeriod()) { + aUMax = aUMin + aSurface->UPeriod(); + } + } else { + // The surface is not V-periodic. Check if aUMin and aUMax + // within bounds. + aUMin = Max(aUMin, aU1); + aUMax = Min(aUMax, aU2); + } + + if (aSurface->IsVPeriodic()) { + // The surface is V-periodic. Check if a new V range is less + // then a period. + if (aVMax - aVMin > aSurface->VPeriod()) { + aVMax = aVMin + aSurface->VPeriod(); + } + } else { + // The surface is not V-periodic. Check if aVMin and aVMax + // within bounds. + aVMin = Max(aVMin, aV1); + aVMax = Min(aVMax, aV2); + } + + if (aUMax - aUMin > aTol && aVMax - aVMin > aTol) { + // Create a new edge. + BRepBuilderAPI_MakeFace aMF + (aSurface, aUMin, aUMax, aVMin, aVMax, aTol); + + if (aMF.IsDone()) { + aResult = aMF.Shape(); + } + } + } + + return aResult; +} + //================================================================================ /*! * \brief Returns a name of creation operation and names and values of creation parameters @@ -1217,15 +1901,38 @@ GetCreationInformation(std::string& theOperationName, AddParam( theParams, "Wires/edges", aCI.GetShapes() ); AddParam( theParams, "Is planar wanted", aCI.GetIsPlanar() ); break; + case FACE_FROM_SURFACE: + { + theOperationName = "FACE"; + + Handle(TColStd_HSequenceOfTransient) shapes = aCI.GetShapes(); + + if (shapes.IsNull() == Standard_False) { + Standard_Integer aNbShapes = shapes->Length(); + + if (aNbShapes > 0) { + AddParam(theParams, "Face", shapes->Value(1)); + + if (aNbShapes > 1) { + AddParam(theParams, "Wire", shapes->Value(2)); + } + } + } + break; + } case SHELL_FACES: theOperationName = "SHELL"; AddParam( theParams, "Objects", aCI.GetShapes() ); break; - case SOLID_SHELL: case SOLID_SHELLS: theOperationName = "SOLID"; AddParam( theParams, "Objects", aCI.GetShapes() ); break; + case SOLID_FACES: + theOperationName = "SOLID_FROM_FACES"; + AddParam( theParams, "Objects", aCI.GetShapes() ); + AddParam( theParams, "Is intersect", aCI.GetIsIntersect() ); + break; case COMPOUND_SHAPES: theOperationName = "COMPOUND"; AddParam( theParams, "Objects", aCI.GetShapes() ); @@ -1254,7 +1961,13 @@ GetCreationInformation(std::string& theOperationName, if ( !shapes.IsNull() && shapes->Length() > 1 ) AddParam( theParams, "Shape", shapes->Value(2) ); AddParam( theParams, "Shape type", TopAbs_ShapeEnum( aCI.GetSubShapeType() )); - AddParam( theParams, "State", TopAbs_State((int) aCI.GetTolerance() )); + AddParam( theParams, "State" ); + GEOMAlgo_State st = GEOMAlgo_State( (int) ( aCI.GetTolerance()+0.1 ) ); + const char* stName[] = { "UNKNOWN","IN","OUT","ON","ONIN","ONOUT","INOUT" }; + if ( 0 <= st && st <= GEOMAlgo_ST_INOUT ) + theParams.back() << stName[ st ]; + else + theParams.back() << (int) st; break; } case SHAPE_ISOLINE: @@ -1267,6 +1980,45 @@ GetCreationInformation(std::string& theOperationName, AddParam(theParams, "Parameter", aII.GetParameter()); break; } + case EDGE_UV: + { + GEOMImpl_IShapeExtend aSE (function); + + theOperationName = "EDGE_EXTEND"; + AddParam(theParams, "Edge", aSE.GetShape()); + AddParam(theParams, "Min", aSE.GetUMin()); + AddParam(theParams, "Max", aSE.GetUMax()); + break; + } + case FACE_UV: + { + GEOMImpl_IShapeExtend aSE (function); + + theOperationName = "FACE_EXTEND"; + AddParam(theParams, "Face", aSE.GetShape()); + AddParam(theParams, "UMin", aSE.GetUMin()); + AddParam(theParams, "UMax", aSE.GetUMax()); + AddParam(theParams, "VMin", aSE.GetVMin()); + AddParam(theParams, "VMax", aSE.GetVMax()); + break; + } + case SURFACE_FROM_FACE: + { + GEOMImpl_IShapeExtend aSE (function); + + theOperationName = "SURFACE_FROM_FACE"; + AddParam(theParams, "Face", aSE.GetShape()); + break; + } + case EXTRACTION: + { + GEOMImpl_IExtract aCI (function); + + theOperationName = "EXTRACTION"; + AddParam(theParams, "Main Shape", aCI.GetShape()); + AddParam(theParams, "Sub-shape IDs", aCI.GetSubShapeIDs()); + break; + } default: return false; } @@ -1274,7 +2026,6 @@ GetCreationInformation(std::string& theOperationName, return true; } -IMPLEMENT_STANDARD_HANDLE (GEOMImpl_ShapeDriver,GEOM_BaseDriver); IMPLEMENT_STANDARD_RTTIEXT (GEOMImpl_ShapeDriver,GEOM_BaseDriver); //modified by NIZNHY-PKV Wed Dec 28 13:48:31 2011f