X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FGEOMImpl%2FGEOMImpl_IShapesOperations.cxx;h=1a7c432055c799963b05d2bf1239cad8642453a0;hb=ed87a1f7c81ec39992aff1f463d73dc81e5791e0;hp=ce0fa360ffcce3ba1cd193ca4d5594eb913f120b;hpb=d37d50070c8c0071420dd8dc71cd43bfc5ddc001;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index ce0fa360f..1a7c43205 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -34,11 +34,13 @@ #include "GEOMImpl_VectorDriver.hxx" #include "GEOMImpl_ShapeDriver.hxx" #include "GEOMImpl_GlueDriver.hxx" +#include "GEOMImpl_FillingDriver.hxx" #include "GEOMImpl_IVector.hxx" #include "GEOMImpl_IShapes.hxx" #include "GEOMImpl_IShapeExtend.hxx" #include "GEOMImpl_IGlue.hxx" +#include "GEOMImpl_IFilling.hxx" #include "GEOMImpl_Block6Explorer.hxx" #include "GEOMImpl_IHealingOperations.hxx" @@ -135,6 +137,63 @@ #include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC +namespace { + + //================================================================================ + /*! + * \brief Return normal to face at extrema point + */ + //================================================================================ + + gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema) + { + gp_Vec defaultNorm(1,0,0); // to have same normals on different faces + try { + // get UV at extrema point + Standard_Real u,v, f,l; + switch ( extrema.SupportTypeShape2(1) ) { + case BRepExtrema_IsInFace: { + extrema.ParOnFaceS2(1, u, v ); + break; + } + case BRepExtrema_IsOnEdge: { + TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1)); + Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l ); + extrema.ParOnEdgeS2( 1, u ); + gp_Pnt2d uv = pcurve->Value( u ); + u = uv.Coord(1); + v = uv.Coord(2); + break; + } + case BRepExtrema_IsVertex: return defaultNorm; + } + // get derivatives + BRepAdaptor_Surface surface( face, false ); + gp_Vec du, dv; gp_Pnt p; + surface.D1( u, v, p, du, dv ); + + return du ^ dv; + + } catch (Standard_Failure ) { + } + return defaultNorm; + } + + void AddFlatSubShapes(const TopoDS_Shape& S, TopTools_ListOfShape& L, TopTools_MapOfShape& M) + { + if (S.ShapeType() != TopAbs_COMPOUND) { + L.Append(S); + } + else { + TopoDS_Iterator It(S, Standard_True, Standard_True); + for (; It.More(); It.Next()) { + TopoDS_Shape SS = It.Value(); + if (M.Add(SS)) + AddFlatSubShapes(SS, L, M); + } + } + } +} //============================================================================= /*! @@ -620,6 +679,107 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceFromSurface return aShape; } +//============================================================================= +/*! + * MakeFaceWithConstraints + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWithConstraints + (std::list theConstraints) +{ + SetErrorCode(KO); + + //Add a new object + Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FILLING); + + //Add a new function + Handle(GEOM_Function) aFunction = + aShape->AddFunction(GEOMImpl_FillingDriver::GetID(), FILLING_ON_CONSTRAINTS); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_FillingDriver::GetID()) return NULL; + + GEOMImpl_IFilling aCI (aFunction); + Handle(TColStd_HSequenceOfTransient) aConstraints = new TColStd_HSequenceOfTransient; + + // Shapes + std::list::iterator it = theConstraints.begin(); + while (it != theConstraints.end()) { + Handle(GEOM_Object) anObject = (*it); + if ( anObject.IsNull() || anObject->GetValue().ShapeType() != TopAbs_EDGE ) { + SetErrorCode("NULL argument edge for the face construction"); + return NULL; + } + Handle(GEOM_Function) aRefSh = anObject->GetLastFunction(); + aConstraints->Append(aRefSh); + it++; + if ( it != theConstraints.end() ) { + Handle(GEOM_Object) aFace = (*it); + if ( aFace.IsNull() ) { + // null constraint face - it is a valid case + it++; + continue; + } + if ( aFace->GetValue().ShapeType() != TopAbs_FACE ) + // constraint face can be omitted - it is a valid case + continue; + if ( IsSubShapeBelongsTo( anObject, 0, aFace, 0 ) ) { + // valid constraint + aRefSh = aFace->GetLastFunction(); + aConstraints->Append(aRefSh); + it++; + } + else { + // bad constraint + SetErrorCode("Face is NULL or not connected to the Edge"); + return NULL; + } + } + } + aCI.SetShapes( aConstraints ); + + //Compute the shape + Standard_Boolean isWarning = Standard_False; + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Shape driver failed"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + // to provide warning + if (!aFunction->GetValue().IsNull()) { + isWarning = Standard_True; + } else { + return NULL; + } + } + + //Make a Python command + GEOM::TPythonDump pd (aFunction); + pd << aShape << " = geompy.MakeFaceWithConstraints(["; + + // Constraints + it = theConstraints.begin(); + if (it != theConstraints.end() ) { + pd << (*it++); + while (it != theConstraints.end()) { + Handle(GEOM_Object) anObject = (*it++); + if( !anObject.IsNull() ) + pd << ", " << anObject; + } + } + pd << "])"; + + // to provide warning + if (!isWarning) SetErrorCode(OK); + return aShape; +} + //============================================================================= /*! * MakeShell @@ -725,6 +885,77 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape return aShape; } +//============================================================================= +/*! + * MakeSolidFromConnectedFaces + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidFromConnectedFaces + (std::list theFacesOrShells, + const Standard_Boolean isIntersect) +{ + SetErrorCode(KO); + + //Add a new object + Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID); + + //Add a new function + Handle(GEOM_Function) aFunction = + aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_FACES); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL; + + GEOMImpl_IShapes aCI (aFunction); + + Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient; + + // Shapes + std::list::iterator it = theFacesOrShells.begin(); + for (; it != theFacesOrShells.end(); it++) { + Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction(); + if (aRefSh.IsNull()) { + SetErrorCode("NULL argument shape for the shape construction"); + return NULL; + } + aShapesSeq->Append(aRefSh); + } + aCI.SetShapes(aShapesSeq); + aCI.SetIsIntersect(isIntersect); + + //Compute the shape + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Shape driver failed"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump pd (aFunction); + pd << aSolid << " = geompy.MakeSolidFromConnectedFaces(["; + + // Shapes + it = theFacesOrShells.begin(); + if (it != theFacesOrShells.end()) { + pd << (*it++); + while (it != theFacesOrShells.end()) { + pd << ", " << (*it++); + } + } + pd << "]," << (isIntersect ? "True" : "False") << ")"; + + SetErrorCode(OK); + return aSolid; +} + //============================================================================= /*! * MakeGlueFaces @@ -1298,17 +1529,20 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode TopTools_ListOfShape listShape; if (aShape.ShapeType() == TopAbs_COMPOUND && - (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE || - TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID || - TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) + (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND)) { TopoDS_Iterator It (aShape, Standard_True, Standard_True); for (; It.More(); It.Next()) { - if (mapShape.Add(It.Value())) { - if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE || - TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) { - listShape.Append(It.Value()); + TopoDS_Shape SS = It.Value(); + if (mapShape.Add(SS)) { + if (theShapeType == TopAbs_FLAT) { + AddFlatSubShapes(SS, listShape, mapShape); + } + else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) { + listShape.Append(SS); } + // VSR: for EXPLODE_NEW_INCLUDE_MAIN and EXPLODE_OLD_INCLUDE_MAIN: + // it seems it is necessary to add top-level shape if theShapeType == TopAbs_COMPOUND } } } @@ -1320,7 +1554,7 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode listShape.Append(exp.Current()); } - if (listShape.IsEmpty()) { + if (listShape.IsEmpty()){ //SetErrorCode("The given shape has no sub-shapes of the requested type"); SetErrorCode(NOT_FOUND_ANY); // NPAL18017 return aSeq; @@ -1364,16 +1598,15 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode // Put this subshape in the list of sub-shapes of theMainShape aMainShape->AddSubShapeReference(aFunction); } - if (!anObj.IsNull()) { - aSeq->Append(anObj); + aSeq->Append(anObj); - // for python command - TDF_Tool::Entry(anObj->GetEntry(), anEntry); - anAsciiList += anEntry; - anAsciiList += ","; - } - } + // for python command + TDF_Tool::Entry(anObj->GetEntry(), anEntry); + anAsciiList += anEntry; + anAsciiList += ","; + } + } //Make a Python command anAsciiList.Trunc(anAsciiList.Length() - 1); @@ -1422,16 +1655,17 @@ Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs TopTools_ListOfShape listShape; if (aShape.ShapeType() == TopAbs_COMPOUND && - (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE || - TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID || - TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) + (theShapeType == TopAbs_SHAPE || theShapeType == TopAbs_FLAT || theShapeType == TopAbs_COMPOUND)) { TopoDS_Iterator It (aShape, Standard_True, Standard_True); for (; It.More(); It.Next()) { - if (mapShape.Add(It.Value())) { - if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE || - TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) { - listShape.Append(It.Value()); + TopoDS_Shape SS = It.Value(); + if (mapShape.Add(SS)) { + if (theShapeType == TopAbs_FLAT) { + AddFlatSubShapes(SS, listShape, mapShape); + } + else if (theShapeType == TopAbs_SHAPE || theShapeType == SS.ShapeType()) { + listShape.Append(SS); } } } @@ -1809,6 +2043,39 @@ TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(G return aTypeName; } +//============================================================================= +/*! + * IsSubShapeBelongsTo + */ +//============================================================================= +Standard_Boolean GEOMImpl_IShapesOperations::IsSubShapeBelongsTo( Handle(GEOM_Object) theSubObject, + const Standard_Integer theSubObjectIndex, + Handle(GEOM_Object) theObject, + const Standard_Integer theObjectIndex) +{ + if ( theObject.IsNull() || theSubObject.IsNull() ) + return false; + + TopoDS_Shape shape = theObject->GetValue(); + TopoDS_Shape subShape = theSubObject->GetValue(); + + if ( shape.IsNull() || subShape.IsNull() ) + return false; + + TopTools_IndexedMapOfShape anIndices; + if ( theObjectIndex > 0 ) { + TopExp::MapShapes( shape, anIndices ); + shape = anIndices.FindKey(theObjectIndex); + } + if ( theSubObjectIndex > 0 ) { + TopExp::MapShapes( subShape, anIndices ); + subShape = anIndices.FindKey(theSubObjectIndex); + } + + TopExp::MapShapes( shape, anIndices ); + return anIndices.Contains( subShape ); +} + //============================================================================= /*! * NumberOfSubShapes @@ -1850,33 +2117,41 @@ Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes */ try { - OCC_CATCH_SIGNALS; - int iType, nbTypes [TopAbs_SHAPE]; - for (iType = 0; iType < TopAbs_SHAPE; ++iType) - nbTypes[iType] = 0; - nbTypes[aShape.ShapeType()]++; - - TopTools_MapOfShape aMapOfShape; - aMapOfShape.Add(aShape); - TopTools_ListOfShape aListOfShape; - aListOfShape.Append(aShape); - - TopTools_ListIteratorOfListOfShape itL (aListOfShape); - for (; itL.More(); itL.Next()) { - TopoDS_Iterator it (itL.Value()); - for (; it.More(); it.Next()) { - TopoDS_Shape s = it.Value(); - if (aMapOfShape.Add(s)) { - aListOfShape.Append(s); - nbTypes[s.ShapeType()]++; + if (theShapeType == TopAbs_FLAT) { + TopTools_MapOfShape aMapOfShape; + TopTools_ListOfShape aListOfShape; + AddFlatSubShapes(aShape, aListOfShape, aMapOfShape); + nbShapes = aListOfShape.Extent(); + } + else { + OCC_CATCH_SIGNALS; + int iType, nbTypes [TopAbs_SHAPE]; + for (iType = 0; iType < TopAbs_SHAPE; ++iType) + nbTypes[iType] = 0; + nbTypes[aShape.ShapeType()]++; + + TopTools_MapOfShape aMapOfShape; + aMapOfShape.Add(aShape); + TopTools_ListOfShape aListOfShape; + aListOfShape.Append(aShape); + + TopTools_ListIteratorOfListOfShape itL (aListOfShape); + for (; itL.More(); itL.Next()) { + TopoDS_Iterator it (itL.Value()); + for (; it.More(); it.Next()) { + TopoDS_Shape s = it.Value(); + if (aMapOfShape.Add(s)) { + aListOfShape.Append(s); + nbTypes[s.ShapeType()]++; + } } } + + if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE) + nbShapes = aMapOfShape.Extent(); + else + nbShapes = nbTypes[theShapeType]; } - - if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE) - nbShapes = aMapOfShape.Extent(); - else - nbShapes = nbTypes[theShapeType]; } catch (Standard_Failure) { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); @@ -3850,49 +4125,6 @@ void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, return; } -namespace { - - //================================================================================ - /*! - * \brief Return normal to face at extrema point - */ - //================================================================================ - - gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema) - { - gp_Vec defaultNorm(1,0,0); // to have same normals on different faces - try { - // get UV at extrema point - Standard_Real u,v, f,l; - switch ( extrema.SupportTypeShape2(1) ) { - case BRepExtrema_IsInFace: { - extrema.ParOnFaceS2(1, u, v ); - break; - } - case BRepExtrema_IsOnEdge: { - TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1)); - Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l ); - extrema.ParOnEdgeS2( 1, u ); - gp_Pnt2d uv = pcurve->Value( u ); - u = uv.Coord(1); - v = uv.Coord(2); - break; - } - case BRepExtrema_IsVertex: return defaultNorm; - } - // get derivatives - BRepAdaptor_Surface surface( face, false ); - gp_Vec du, dv; gp_Pnt p; - surface.D1( u, v, p, du, dv ); - - return du ^ dv; - - } catch (Standard_Failure ) { - } - return defaultNorm; - } -} - //============================================================================= /*! * case GetInPlace: @@ -4921,3 +5153,64 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ExtendFace return aResFace; } + +//======================================================================= +//function : MakeSurfaceFromFace +//purpose : +//======================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSurfaceFromFace + (const Handle(GEOM_Object) &theFace) +{ + SetErrorCode(KO); + + if (theFace.IsNull()) { + return NULL; + } + + //Add a new Face object + Handle(GEOM_Object) aResFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE); + + //Add a new Vector function + Handle(GEOM_Function) aFunction = + aResFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), SURFACE_FROM_FACE); + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) { + return NULL; + } + + GEOMImpl_IShapeExtend aCI (aFunction); + + Handle(GEOM_Function) aFace = theFace->GetLastFunction(); + + if (aFace.IsNull()) { + return NULL; + } + + aCI.SetShape(aFace); + + //Compute the Face value + try { + OCC_CATCH_SIGNALS; + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Shape driver failed"); + + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) + << aResFace << " = geompy.MakeSurfaceFromFace(" + << theFace << ")"; + + SetErrorCode(OK); + + return aResFace; +}