From ce4d5383a4bf95d4a023d48532b32403bb9e0b45 Mon Sep 17 00:00:00 2001 From: jfa Date: Fri, 24 Dec 2004 14:31:19 +0000 Subject: [PATCH] Some new methods implemented in BlocksOperations and in ShapesOperations; GlueFaces optimized and improved; CheckCompoundOfBlocks(), GetFaceNearPoint(), GetEdgeNearPoint() optimized --- idl/GEOM_Gen.idl | 119 ++- src/GEOMImpl/GEOMImpl_GlueDriver.cxx | 76 +- src/GEOMImpl/GEOMImpl_GlueDriver.hxx | 5 + src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx | 789 ++++++++++++++++---- src/GEOMImpl/GEOMImpl_IBlocksOperations.hxx | 8 + src/GEOMImpl/GEOMImpl_IShapesOperations.cxx | 699 ++++++++++++++++- src/GEOMImpl/GEOMImpl_IShapesOperations.hxx | 33 +- src/GEOM_I/GEOM_IBlocksOperations_i.cc | 46 ++ src/GEOM_I/GEOM_IBlocksOperations_i.hh | 3 + src/GEOM_I/GEOM_IShapesOperations_i.cc | 257 ++++++- src/GEOM_I/GEOM_IShapesOperations_i.hh | 38 +- src/GEOM_SWIG/batchmode_geompy.py | 12 + src/GEOM_SWIG/geompy.py | 23 + 13 files changed, 1935 insertions(+), 173 deletions(-) diff --git a/idl/GEOM_Gen.idl b/idl/GEOM_Gen.idl index 63f649050..93020d92a 100644 --- a/idl/GEOM_Gen.idl +++ b/idl/GEOM_Gen.idl @@ -814,6 +814,20 @@ module GEOM in long theShapeType, in boolean isSorted); + /*! + * Explode a shape on subshapes of a given type. + * Does the same, as the above method, but returns IDs of sub-shapes, + * not GEOM_Objects. It works faster. + * \param theShape Shape to be exploded. + * \param theShapeType Type of sub-shapes to be retrieved. + * \param isSorted If this parameter is TRUE, sub-shapes will be + * sorted by coordinates of their gravity centers. + * \return List of IDs of sub-shapes of type theShapeType, contained in theShape. + */ + ListOfLong SubShapeAllIDs (in GEOM_Object theShape, + in long theShapeType, + in boolean isSorted); + /*! * Get a sub shape defined by its unique ID inside \a theMainShape * \note The sub shape GEOM_Objects can has ONLY ONE function. @@ -842,6 +856,76 @@ module GEOM * \return The reversed copy of theShape. */ GEOM_Object ChangeOrientation (in GEOM_Object theShape); + + /*! + * Retrieve all free faces from the given shape. + * Free face is a face, which is not shared between two shells of the shape. + * \param theShape Shape to find free faces in. + * \return List of IDs of all free faces, contained in theShape. + */ + ListOfLong GetFreeFacesIDs (in GEOM_Object theShape); + + /*! + * Get all sub-shapes of theShape1 of the given type, shared with theShape2. + * \param theShape1 Shape to find sub-shapes in. + * \param theShape2 Shape to find shared sub-shapes with. + * \param theShapeType Type of sub-shapes to be retrieved. + * \return List of sub-shapes of theShape1, shared with theShape2. + */ + ListOfGO GetSharedShapes (in GEOM_Object theShape1, + in GEOM_Object theShape2, + in long theShapeType); + + /*! + * Get sub-shapes of theShape of the given type, + * laying on the specified plane. + * \param theShape Shape to find sub-shapes of. + * \param theShapeType Type of sub-shapes to be retrieved. + * \param thePlane Face, specifying the plane to find shapes on. + * \return Group of all found sub-shapes. + */ + GEOM_Object GetShapesOnPlane (in GEOM_Object theShape, + in long theShapeType, + in GEOM_Object thePlane); + + /*! + * Get sub-shape of theShape of the given type, + * laying on the specified cylinder. + * \param theShape Shape to find sub-shapes of. + * \param theShapeType Type of sub-shapes to be retrieved. + * \param theAxis Vector (or line, or linear edge), specifying + * axis of the cylinder to find shapes on. + * \param theRadius Radius of the cylinder to find shapes on. + * \return Group of all found sub-shapes. + */ + GEOM_Object GetShapesOnCylinder (in GEOM_Object theShape, + in long theShapeType, + in GEOM_Object theAxis, + in double theRadius); + + /*! + * Get sub-shape of theShape of the given type, + * laying on the specified sphere. + * \param theShape Shape to find sub-shapes of. + * \param theShapeType Type of sub-shapes to be retrieved. + * \param theCenter Point, specifying center of the sphere to find shapes on. + * \param theRadius Radius of the sphere to find shapes on. + * \return Group of all found sub-shapes. + */ + GEOM_Object GetShapesOnSphere (in GEOM_Object theShape, + in long theShapeType, + in GEOM_Object theCenter, + in double theRadius); + + /*! + * Get sub-shape(s) of theShapeWhere, which are + * coincident with \a theShapeWhat or could be a part of it. + * \param theShapeWhere Shape to find sub-shapes of. + * \param theShapeWhat Shape, specifying what to find. + * \return Group of all found sub-shapes or a single found sub-shape. + */ + GEOM_Object GetInPlace (in GEOM_Object theShapeWhere, + in GEOM_Object theShapeWhat); }; /*! @@ -1017,10 +1101,23 @@ module GEOM */ enum BCErrorType { - NOT_BLOCK, /* Each element of the compound should be a Block */ - INVALID_CONNECTION, /* A connection between two Blocks should be an entire face or an entire edge */ - NOT_CONNECTED, /* The compound should be connexe */ - NOT_GLUED /* The glue between two quadrangle faces should be applied */ + /* Each element of the compound should be a Block */ + NOT_BLOCK, + + /* An element is a potential block, but has degenerated edge(s). */ + DEGENERATED_EDGE, + + /* An element is a potential block, but has seam edge(s). */ + SEAM_EDGE, + + /* A connection between two Blocks should be an entire face or an entire edge */ + INVALID_CONNECTION, + + /* The compound should be connexe */ + NOT_CONNECTED, + + /* The glue between two quadrangle faces should be applied */ + NOT_GLUED }; /*! @@ -1137,6 +1234,20 @@ module GEOM in long theDirFace1V, in long theDirFace2V, in long theNbTimesV); + + /*! + * Special operation - propagation + */ + + /*! + * Build all possible propagation groups. + * Propagation group is a set of all edges, opposite to one (main) + * edge of this group directly or through other opposite edges. + * Notion of Opposite Edge make sence only on quadrangle face. + * \param theShape Shape to build propagation groups on. + * \return List of GEOM_Objects, each of them is a propagation group. + */ + ListOfGO Propagate (in GEOM_Object theShape); }; /*! diff --git a/src/GEOMImpl/GEOMImpl_GlueDriver.cxx b/src/GEOMImpl/GEOMImpl_GlueDriver.cxx index cd65a79fc..81e330e30 100644 --- a/src/GEOMImpl/GEOMImpl_GlueDriver.cxx +++ b/src/GEOMImpl/GEOMImpl_GlueDriver.cxx @@ -12,6 +12,7 @@ using namespace std; #include #include +#include //======================================================================= //function : GEOMImpl_GlueDriver @@ -31,6 +32,74 @@ const Standard_GUID& GEOMImpl_GlueDriver::GetID() return aGlueDriver; } +//======================================================================= +//function : GlueFacesWithWarnings +//purpose : +//======================================================================= +TopoDS_Shape GEOMImpl_GlueDriver::GlueFacesWithWarnings (const TopoDS_Shape& theShape, + const Standard_Real theTolerance, + TCollection_AsciiString& theWarning) const +{ + Standard_Integer iErr, iWrn; + TopoDS_Shape aRes; + GEOMAlgo_Gluer aGluer; + + aGluer.SetShape(theShape); + aGluer.SetTolerance(theTolerance); + aGluer.SetCheckGeometry(Standard_True); + + aGluer.Perform(); + + iErr = aGluer.ErrorStatus(); + if (iErr) { + switch (iErr) { + case 2: + Standard_Failure::Raise("No vertices found in source shape"); + break; + case 5: + Standard_Failure::Raise("Source shape is Null"); + break; + case 6: + Standard_Failure::Raise("Result shape is Null"); + break; + case 200: + Standard_Failure::Raise("Error occured during check of geometric coincidence"); + break; + default: + { + // description of all errors see in GEOMAlgo_Gluer.cxx + TCollection_AsciiString aMsg ("Error in GEOMAlgo_Gluer with code "); + aMsg += TCollection_AsciiString(iErr); + Standard_Failure::Raise(aMsg.ToCString()); + break; + } + } + return aRes; + } + + iWrn = aGluer.WarningStatus(); + if (iWrn) { + switch (iWrn) { + case 1: + { + Standard_Integer nbAlone = aGluer.AloneShapes(); + theWarning = TCollection_AsciiString(nbAlone); + theWarning += " solids can not be glued by faces"; + } + break; + default: + // description of all warnings see in GEOMAlgo_Gluer.cxx + theWarning = "Warning in GEOMAlgo_Gluer with code "; + theWarning += TCollection_AsciiString(iWrn); + break; + } + } + + aRes = aGluer.Result(); + + return aRes; +} + //======================================================================= //function : GlueFaces //purpose : @@ -106,6 +175,7 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const Standard_Integer aType = aFunction->GetType(); TopoDS_Shape aShape; + TCollection_AsciiString aWrn; if (aType == GLUE_FACES) { Handle(GEOM_Function) aRefBase = aCI.GetBase(); @@ -115,7 +185,7 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const } Standard_Real tol3d = aCI.GetTolerance(); - aShape = GlueFaces(aShapeBase, tol3d); + aShape = GlueFacesWithWarnings(aShapeBase, tol3d, aWrn); } else { } @@ -125,6 +195,10 @@ Standard_Integer GEOMImpl_GlueDriver::Execute(TFunction_Logbook& log) const log.SetTouched(Label()); + if (!aWrn.IsEmpty()) { + Standard_Failure::Raise(aWrn.ToCString()); + } + return 1; } diff --git a/src/GEOMImpl/GEOMImpl_GlueDriver.hxx b/src/GEOMImpl/GEOMImpl_GlueDriver.hxx index 489f6a11c..c8f2679cd 100644 --- a/src/GEOMImpl/GEOMImpl_GlueDriver.hxx +++ b/src/GEOMImpl/GEOMImpl_GlueDriver.hxx @@ -97,6 +97,7 @@ class Handle(GEOMImpl_GlueDriver) : public Handle(TFunction_Driver) { #include #endif #include +#include class TColStd_SequenceOfExtendedString; @@ -130,6 +131,10 @@ Standard_EXPORT ~GEOMImpl_GlueDriver() {}; Standard_EXPORT static TopoDS_Shape GlueFaces (const TopoDS_Shape& theShape, const Standard_Real theTolerance); +Standard_EXPORT TopoDS_Shape GlueFacesWithWarnings (const TopoDS_Shape& theShape, + const Standard_Real theTolerance, + TCollection_AsciiString& theWarning) const; + // Type management // Standard_EXPORT friend Handle_Standard_Type& GEOMImpl_GlueDriver_Type_(); diff --git a/src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx b/src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx index 9b7aedc80..14b04f173 100644 --- a/src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IBlocksOperations.cxx @@ -12,6 +12,11 @@ using namespace std; #include "GEOM_Function.hxx" +#include "GEOMAlgo_GlueAnalyser.hxx" +#include "GEOMAlgo_CoupleOfShapes.hxx" +#include "GEOMAlgo_ListOfCoupleOfShapes.hxx" +#include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx" + #include "utilities.h" #include "OpUtil.hxx" #include "Utils_ExceptHandlers.hxx" @@ -19,10 +24,13 @@ using namespace std; #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -34,23 +42,33 @@ using namespace std; #include #include #include +#include #include #include #include #include #include #include +#include #include #include +#include #include -#include #include + +#include +#include + #include #include #include #include +//#include + +#include + #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC //============================================================================= @@ -1214,6 +1232,9 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint (Handle(GEOM_Object) theShape, Handle(GEOM_Object) thePoint) { +// OSD_Timer timer1, timer2, timer3, timer4, timer5; +// timer1.Start(); + SetErrorCode(KO); //New object @@ -1250,51 +1271,66 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint TopoDS_Vertex aVert = TopoDS::Vertex(anArg); gp_Pnt aPnt = BRep_Tool::Pnt(aVert); + Standard_Real PX, PY, PZ; + aPnt.Coord(PX, PY, PZ); - // 1. Explode blocks on faces - TopTools_MapOfShape mapShape; - Standard_Integer nbFaces = 0; +// timer1.Stop(); +// timer2.Start(); + + // 1. Classify the point relatively each face + Standard_Integer nearest = 2, nbFound = 0; + TopTools_DataMapOfShapeInteger mapShapeDist; TopExp_Explorer exp (aBlockOrComp, TopAbs_FACE); for (; exp.More(); exp.Next()) { - if (mapShape.Add(exp.Current())) { - nbFaces++; - } - } + TopoDS_Shape aFace = exp.Current(); + + if (!mapShapeDist.IsBound(aFace)) { + Standard_Integer aDistance = 2; + + // 1.a. Classify relatively Surface + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace)); + Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf); + gp_Pnt2d p2dOnSurf = aSurfAna->ValueOfUV(aPnt, Precision::Confusion()); + gp_Pnt p3dOnSurf = aSurfAna->Value(p2dOnSurf); + Standard_Real aDist = p3dOnSurf.Distance(aPnt); + if (aDist > Precision::Confusion()) { + // OUT of Surface + aDistance = 1; + } else { + // 1.b. Classify relatively the face itself + BRepClass_FaceClassifier FC (TopoDS::Face(aFace), p2dOnSurf, Precision::Confusion()); + if (FC.State() == TopAbs_IN) { + aDistance = -1; + } else if (FC.State() == TopAbs_ON) { + aDistance = 0; + } else { // OUT + aDistance = 1; + } + } - mapShape.Clear(); - Standard_Integer ind = 1; - TopTools_Array1OfShape aFaces (1, nbFaces); - TColStd_Array1OfInteger aDistances (1, nbFaces); - for (exp.Init(aBlockOrComp, TopAbs_FACE); exp.More(); exp.Next()) { - if (mapShape.Add(exp.Current())) { - TopoDS_Shape aFace = exp.Current(); - aFaces(ind) = aFace; - - // 2. Classify the point relatively each face - BRepClass_FaceClassifier FC (TopoDS::Face(aFace), aPnt, Precision::Confusion()); - if (FC.State() == TopAbs_IN) { - aDistances(ind) = -1; - } else if (FC.State() == TopAbs_ON) { - aDistances(ind) = 0; - } else { // OUT - aDistances(ind) = 1; + if (aDistance < nearest) { + nearest = aDistance; + aShape = aFace; + nbFound = 1; + + // A first found face, containing the point inside, will be returned. + // It is the solution, if there are no + // coincident or intersecting faces in the compound. + if (nearest == -1) break; + + } else if (aDistance == nearest) { + nbFound++; + } else { } - ind++; - } - } - // 3. Define face, containing the point or having minimum distance to it - Standard_Integer nearest = 2, nbFound = 0; - for (ind = 1; ind <= nbFaces; ind++) { - if (aDistances(ind) < nearest) { - nearest = aDistances(ind); - aShape = aFaces(ind); - nbFound = 1; - } else if (aDistances(ind) == nearest) { - nbFound++; - } else { - } + mapShapeDist.Bind(aFace, aDistance); + } // if (!mapShapeDist.IsBound(aFace)) } + +// timer2.Stop(); +// timer3.Start(); + + // 2. Define face, containing the point or having minimum distance to it if (nbFound > 1) { if (nearest == 0) { // The point is on boundary of some faces and there are @@ -1306,40 +1342,66 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint // The point is outside some faces and there are // no faces, having the point inside or on boundary. // We will get a nearest face - Standard_Real minDist = RealLast(); - for (ind = 1; ind <= nbFaces; ind++) { - if (aDistances(ind) == 1) { - BRepExtrema_DistShapeShape aDistTool (aVert, aFaces(ind)); - if (!aDistTool.IsDone()) { - SetErrorCode("Can not find a distance from the given point to one of faces"); - return NULL; + Standard_Real bigReal = RealLast(); + Standard_Real minDist = bigReal; + TopTools_DataMapIteratorOfDataMapOfShapeInteger mapShapeDistIter (mapShapeDist); + for (; mapShapeDistIter.More(); mapShapeDistIter.Next()) { + if (mapShapeDistIter.Value() == 1) { + TopoDS_Shape aFace = mapShapeDistIter.Key(); + Standard_Real aDist = bigReal; + + // 2.a. Fast check of distance - if point projection on surface is on face + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aFace)); + Handle(ShapeAnalysis_Surface) aSurfAna = new ShapeAnalysis_Surface (aSurf); + gp_Pnt2d p2dOnSurf = aSurfAna->ValueOfUV(aPnt, Precision::Confusion()); + gp_Pnt p3dOnSurf = aSurfAna->Value(p2dOnSurf); + aDist = p3dOnSurf.Distance(aPnt); + + BRepClass_FaceClassifier FC (TopoDS::Face(aFace), p2dOnSurf, Precision::Confusion()); + if (FC.State() == TopAbs_OUT) { + if (aDist < minDist) { + // 2.b. Slow check - if point projection on surface is outside of face + BRepExtrema_DistShapeShape aDistTool (aVert, aFace); + if (!aDistTool.IsDone()) { + SetErrorCode("Can not find a distance from the given point to one of faces"); + return NULL; + } + aDist = aDistTool.Value(); + } else { + aDist = bigReal; + } } - Standard_Real aDist = aDistTool.Value(); - if (aDist < minDist) { - minDist = aDist; - aShape = aFaces(ind); - } - } - } - } else { // nearest == -1 - // The point is inside some faces. - // We will get a face with nearest center - Standard_Real minDist = RealLast(); - for (ind = 1; ind <= nbFaces; ind++) { - if (aDistances(ind) == -1) { - GProp_GProps aSystem; - BRepGProp::SurfaceProperties(aFaces(ind), aSystem); - gp_Pnt aCenterMass = aSystem.CentreOfMass(); - Standard_Real aDist = aCenterMass.Distance(aPnt); if (aDist < minDist) { minDist = aDist; - aShape = aFaces(ind); + aShape = aFace; } } } + } else { // nearest == -1 +// // The point is inside some faces. +// // We will get a face with nearest center +// Standard_Real minDist = RealLast(); +// TopTools_DataMapIteratorOfDataMapOfShapeInteger mapShapeDistIter (mapShapeDist); +// for (; mapShapeDistIter.More(); mapShapeDistIter.Next()) { +// if (mapShapeDistIter.Value() == -1) { +// TopoDS_Shape aFace = mapShapeDistIter.Key(); +// GProp_GProps aSystem; +// BRepGProp::SurfaceProperties(aFace, aSystem); +// gp_Pnt aCenterMass = aSystem.CentreOfMass(); +// +// Standard_Real aDist = aCenterMass.Distance(aPnt); +// if (aDist < minDist) { +// minDist = aDist; +// aShape = aFace; +// } +// } +// } } - } + } // if (nbFound > 1) + +// timer3.Stop(); +// timer4.Start(); if (nbFound == 0) { SetErrorCode("There are no faces near the given point"); @@ -1351,6 +1413,8 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint anArray->SetValue(1, anIndices.FindIndex(aShape)); aResult = GetEngine()->AddSubShape(theShape, anArray); } + +// timer4.Stop(); } catch (Standard_Failure) { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); @@ -1358,6 +1422,8 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint return NULL; } +// timer5.Start(); + //The GetFaceNearPoint() doesn't change object so no new function is required. Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); @@ -1375,6 +1441,16 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetFaceNearPoint aFunction->SetDescription(aNewDescr); SetErrorCode(OK); + +// timer5.Stop(); +// +// cout << "Show current face times:" << endl; +// timer1.Show(); +// timer2.Show(); +// timer3.Show(); +// timer4.Show(); +// timer5.Show(); + return aResult; } @@ -1585,7 +1661,9 @@ Standard_Boolean GEOMImpl_IBlocksOperations::IsCompoundOfBlocks //============================================================================= void AddBlocksFrom (const TopoDS_Shape& theShape, TopTools_ListOfShape& BLO, - TopTools_ListOfShape& NOT) + TopTools_ListOfShape& NOT, + TopTools_ListOfShape& DEG, + TopTools_ListOfShape& SEA) { TopAbs_ShapeEnum aType = theShape.ShapeType(); switch (aType) { @@ -1594,7 +1672,7 @@ void AddBlocksFrom (const TopoDS_Shape& theShape, { TopoDS_Iterator It (theShape); for (; It.More(); It.Next()) { - AddBlocksFrom(It.Value(), BLO, NOT); + AddBlocksFrom(It.Value(), BLO, NOT, DEG, SEA); } } break; @@ -1603,25 +1681,67 @@ void AddBlocksFrom (const TopoDS_Shape& theShape, TopTools_MapOfShape mapFaces; TopExp_Explorer expF (theShape, TopAbs_FACE); Standard_Integer nbFaces = 0; - Standard_Integer nbEdges = 0; + Standard_Boolean hasNonQuadr = Standard_False; + Standard_Boolean hasDegenerated = Standard_False; + Standard_Boolean hasSeam = Standard_False; for (; expF.More(); expF.Next()) { if (mapFaces.Add(expF.Current())) { nbFaces++; if (nbFaces > 6) break; // Check number of edges in the face + Standard_Integer nbEdges = 0; + TopTools_MapOfShape mapEdges; + + // get wire TopoDS_Shape aF = expF.Current(); - TopExp_Explorer expE (aF, TopAbs_EDGE); - nbEdges = 0; - for (; expE.More(); expE.Next()) { - nbEdges++; - if (nbEdges > 4) break; + TopExp_Explorer wires (aF, TopAbs_WIRE); + if (!wires.More()) { + // no wire in the face + hasNonQuadr = Standard_True; + break; + } + TopoDS_Shape aWire = wires.Current(); + wires.Next(); + if (wires.More()) { + // multiple wires in the face + hasNonQuadr = Standard_True; + break; + } + + // iterate on wire + BRepTools_WireExplorer aWE (TopoDS::Wire(aWire), TopoDS::Face(aF)); + for (; aWE.More(); aWE.Next(), nbEdges++) { + if (BRep_Tool::Degenerated(aWE.Current())) { + // degenerated edge found + hasDegenerated = Standard_True; +// break; + } + if (mapEdges.Contains(aWE.Current())) { + // seam edge found + hasSeam = Standard_True; +// break; + } + mapEdges.Add(aWE.Current()); + } + if (nbEdges != 4) { + hasNonQuadr = Standard_True; } - if (nbEdges != 4) break; } } - if (nbFaces == 6 && nbEdges == 4) { - BLO.Append(theShape); + if (nbFaces == 6) { + if (hasDegenerated || hasSeam) { + if (hasDegenerated) { + DEG.Append(theShape); + } + if (hasSeam) { + SEA.Append(theShape); + } + } else if (hasNonQuadr) { + NOT.Append(theShape); + } else { + BLO.Append(theShape); + } } else { NOT.Append(theShape); } @@ -1649,20 +1769,13 @@ Standard_Integer BlocksRelation (const TopoDS_Shape& theBlock1, Bnd_Box B1, B2; BRepBndLib::Add(theBlock1, B1); BRepBndLib::Add(theBlock2, B2); -// BRepBndLib::AddClose(theBlock1, B1); -// BRepBndLib::AddClose(theBlock2, B2); B1.Get(Xmin1, Ymin1, Zmin1, Xmax1, Ymax1, Zmax1); B2.Get(Xmin2, Ymin2, Zmin2, Xmax2, Ymax2, Zmax2); if (Xmax2 < Xmin1 || Xmax1 < Xmin2 || Ymax2 < Ymin1 || Ymax1 < Ymin2 || Zmax2 < Zmin1 || Zmax1 < Zmin2) { -// Standard_Real prec = Precision::Confusion(); -// if (prec < Xmin1 - Xmax2 || prec < Xmin2 - Xmax1 || -// prec < Ymin1 - Ymax2 || prec < Ymin2 - Ymax1 || -// prec < Zmin1 - Zmax2 || prec < Zmin2 - Zmax1) { return REL_NOT_CONNECTED; } - // to be done BRepExtrema_DistShapeShape dst (theBlock1, theBlock2); if (!dst.IsDone()) { @@ -1863,10 +1976,10 @@ Standard_Boolean HasAnyConnection (const Standard_Integer theBlockIndex, //============================================================================= /*! - * CheckCompoundOfBlocks + * CheckCompoundOfBlocksOld */ //============================================================================= -Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocks +Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocksOld (Handle(GEOM_Object) theCompound, list& theErrors) { @@ -1883,16 +1996,40 @@ Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocks // 1. Report non-blocks TopTools_ListOfShape NOT; // Not blocks + TopTools_ListOfShape DEG; // Hexahedral solids, having degenerated edges + TopTools_ListOfShape SEA; // Hexahedral solids, having seam edges TopTools_ListOfShape BLO; // All blocks from the given compound - AddBlocksFrom(aBlockOrComp, BLO, NOT); + AddBlocksFrom(aBlockOrComp, BLO, NOT, DEG, SEA); if (NOT.Extent() > 0) { isCompOfBlocks = Standard_False; BCError anErr; anErr.error = NOT_BLOCK; - TopTools_ListIteratorOfListOfShape NOTit (NOT); - for (; NOTit.More(); NOTit.Next()) { - anErr.incriminated.push_back(anIndices.FindIndex(NOTit.Value())); + TopTools_ListIteratorOfListOfShape it (NOT); + for (; it.More(); it.Next()) { + anErr.incriminated.push_back(anIndices.FindIndex(it.Value())); + } + theErrors.push_back(anErr); + } + + if (DEG.Extent() > 0) { + isCompOfBlocks = Standard_False; + BCError anErr; + anErr.error = DEGENERATED_EDGE; + TopTools_ListIteratorOfListOfShape it (DEG); + for (; it.More(); it.Next()) { + anErr.incriminated.push_back(anIndices.FindIndex(it.Value())); + } + theErrors.push_back(anErr); + } + + if (SEA.Extent() > 0) { + isCompOfBlocks = Standard_False; + BCError anErr; + anErr.error = SEAM_EDGE; + TopTools_ListIteratorOfListOfShape it (SEA); + for (; it.More(); it.Next()) { + anErr.incriminated.push_back(anIndices.FindIndex(it.Value())); } theErrors.push_back(anErr); } @@ -2012,6 +2149,12 @@ TCollection_AsciiString GEOMImpl_IBlocksOperations::PrintBCErrors case NOT_BLOCK: aDescr += "\nNot a Blocks: "; break; + case DEGENERATED_EDGE: + aDescr += "\nHexahedral solids with degenerated edges: "; + break; + case SEAM_EDGE: + aDescr += "\nHexahedral solids with seam edges: "; + break; case INVALID_CONNECTION: aDescr += "\nInvalid connection between two blocks: "; break; @@ -2038,6 +2181,202 @@ TCollection_AsciiString GEOMImpl_IBlocksOperations::PrintBCErrors return aDescr; } +//============================================================================= +/*! + * CheckCompoundOfBlocks + */ +//============================================================================= +Standard_Boolean GEOMImpl_IBlocksOperations::CheckCompoundOfBlocks + (Handle(GEOM_Object) theCompound, + list& theErrors) +{ + SetErrorCode(KO); + + if (theCompound.IsNull()) return Standard_False; + TopoDS_Shape aBlockOrComp = theCompound->GetValue(); + + Standard_Boolean isCompOfBlocks = Standard_True; + + // Map sub-shapes and their indices + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aBlockOrComp, anIndices); + + // 1. Separate blocks from non-blocks + TopTools_ListOfShape NOT; // Not blocks + TopTools_ListOfShape DEG; // Hexahedral solids, having degenerated edges + TopTools_ListOfShape SEA; // Hexahedral solids, having seam edges + TopTools_ListOfShape BLO; // All blocks from the given compound + AddBlocksFrom(aBlockOrComp, BLO, NOT, DEG, SEA); + + // Report non-blocks + if (NOT.Extent() > 0) { + isCompOfBlocks = Standard_False; + BCError anErr; + anErr.error = NOT_BLOCK; + TopTools_ListIteratorOfListOfShape it (NOT); + for (; it.More(); it.Next()) { + anErr.incriminated.push_back(anIndices.FindIndex(it.Value())); + } + theErrors.push_back(anErr); + } + + // Report solids, having degenerated edges + if (DEG.Extent() > 0) { + isCompOfBlocks = Standard_False; + BCError anErr; + anErr.error = DEGENERATED_EDGE; + TopTools_ListIteratorOfListOfShape it (DEG); + for (; it.More(); it.Next()) { + anErr.incriminated.push_back(anIndices.FindIndex(it.Value())); + } + theErrors.push_back(anErr); + } + + // Report solids, having seam edges + if (SEA.Extent() > 0) { + isCompOfBlocks = Standard_False; + BCError anErr; + anErr.error = SEAM_EDGE; + TopTools_ListIteratorOfListOfShape it (SEA); + for (; it.More(); it.Next()) { + anErr.incriminated.push_back(anIndices.FindIndex(it.Value())); + } + theErrors.push_back(anErr); + } + + Standard_Integer nbBlocks = BLO.Extent(); + if (nbBlocks == 0) { + isCompOfBlocks = Standard_False; + SetErrorCode(OK); + return isCompOfBlocks; + } + if (nbBlocks == 1) { + SetErrorCode(OK); + return isCompOfBlocks; + } + + // Prepare data for 2. and 3. + TColStd_Array2OfInteger aRelations (1, nbBlocks, 1, nbBlocks); + aRelations.Init(REL_NOT_CONNECTED); + + TopTools_IndexedMapOfShape mapBlocks; + + BRep_Builder BB; + TopoDS_Compound aComp; + BB.MakeCompound(aComp); + + TopTools_ListIteratorOfListOfShape BLOit (BLO); + for (; BLOit.More(); BLOit.Next()) { + mapBlocks.Add(BLOit.Value()); + BB.Add(aComp, BLOit.Value()); + } + + // 2. Find glued blocks (having shared faces) + TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks; + GEOMImpl_Block6Explorer::MapShapesAndAncestors + (aComp, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks); + + Standard_Integer prevInd = 0, curInd = 0; + Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent(); + for (; ind <= nbFaces; ind++) { + const TopTools_ListOfShape& aGluedBlocks = mapFaceBlocks.FindFromIndex(ind); + if (aGluedBlocks.Extent() > 1) { // Shared face found + TopTools_ListIteratorOfListOfShape aGluedBlocksIt (aGluedBlocks); + TopoDS_Shape prevBlock, curBlock; + for (; aGluedBlocksIt.More(); aGluedBlocksIt.Next()) { + curBlock = aGluedBlocksIt.Value(); + if (!prevBlock.IsNull()) { + prevInd = mapBlocks.FindIndex(prevBlock); + curInd = mapBlocks.FindIndex(curBlock); + aRelations.SetValue(prevInd, curInd, REL_OK); + aRelations.SetValue(curInd, prevInd, REL_OK); + } + prevBlock = curBlock; + } + } + } + + // 3. Find not glued blocks + GEOMAlgo_GlueAnalyser aGD; + + aGD.SetShape(aComp); + aGD.SetTolerance(Precision::Confusion()); + aGD.SetCheckGeometry(Standard_True); + aGD.Perform(); + + Standard_Integer iErr, iWrn; + iErr = aGD.ErrorStatus(); + if (iErr) { + SetErrorCode("Error in GEOMAlgo_GlueAnalyser"); + return isCompOfBlocks; + } + iWrn = aGD.WarningStatus(); + if (iWrn) { + MESSAGE("Warning in GEOMAlgo_GlueAnalyser"); + } + + // Report not glued blocks + if (aGD.HasSolidsToGlue()) { + isCompOfBlocks = Standard_False; + Standard_Integer aSx1Ind, aSx2Ind; + + const GEOMAlgo_ListOfCoupleOfShapes& aLCS = aGD.SolidsToGlue(); + GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS (aLCS); + for (; aItCS.More(); aItCS.Next()) { + const GEOMAlgo_CoupleOfShapes& aCS = aItCS.Value(); + const TopoDS_Shape& aSx1 = aCS.Shape1(); + const TopoDS_Shape& aSx2 = aCS.Shape2(); + + aSx1Ind = mapBlocks.FindIndex(aSx1); + aSx2Ind = mapBlocks.FindIndex(aSx2); + aRelations.SetValue(aSx1Ind, aSx2Ind, NOT_GLUED); + aRelations.SetValue(aSx2Ind, aSx1Ind, NOT_GLUED); + + BCError anErr; + anErr.error = NOT_GLUED; + anErr.incriminated.push_back(anIndices.FindIndex(aSx1)); + anErr.incriminated.push_back(anIndices.FindIndex(aSx2)); + theErrors.push_back(anErr); + } + } + + // 4. Find largest set of connected (good connection or not glued) blocks + Standard_Integer ibl = 1; + TColStd_MapOfInteger aProcessedMap; + TColStd_MapOfInteger aLargestSet; + TColStd_MapOfInteger aCurrentSet; + for (ibl = 1; ibl <= nbBlocks; ibl++) { + if (!aProcessedMap.Contains(ibl)) { + FindConnected(ibl, aRelations, aProcessedMap, aCurrentSet); + if (aCurrentSet.Extent() > aLargestSet.Extent()) { + aLargestSet = aCurrentSet; + } + } + } + + // 5. Report all blocks, isolated from + BCError anErr; + anErr.error = NOT_CONNECTED; + Standard_Boolean hasIsolated = Standard_False; + for (ibl = 1; ibl <= nbBlocks; ibl++) { + if (!aLargestSet.Contains(ibl)) { + aProcessedMap.Clear(); + if (!HasAnyConnection(ibl, aLargestSet, aRelations, aProcessedMap)) { + // report connection absence + hasIsolated = Standard_True; + anErr.incriminated.push_back(anIndices.FindIndex(mapBlocks.FindKey(ibl))); + } + } + } + if (hasIsolated) { + isCompOfBlocks = Standard_False; + theErrors.push_back(anErr); + } + + SetErrorCode(OK); + return isCompOfBlocks; +} + //============================================================================= /*! * ExplodeCompoundOfBlocks @@ -2153,70 +2492,80 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetBlockNearPoint } if (aBlockOrComp.ShapeType() != TopAbs_COMPOUND && aBlockOrComp.ShapeType() != TopAbs_COMPSOLID) { - SetErrorCode("Shape is neither a block, nor a compound of blocks"); + SetErrorCode("Shape to find block in is not a compound"); return NULL; } TopoDS_Shape anArg = thePoint->GetValue(); if (anArg.IsNull()) { - SetErrorCode("Null shape is given as argument"); + SetErrorCode("Point is null"); return NULL; } if (anArg.ShapeType() != TopAbs_VERTEX) { - SetErrorCode("Element for block identification is not a vertex"); + SetErrorCode("Shape for block identification is not a vertex"); return NULL; } //Compute the Block value try { TopoDS_Shape aShape; + TopoDS_Vertex aVert = TopoDS::Vertex(anArg); gp_Pnt aPnt = BRep_Tool::Pnt(aVert); + Standard_Real PX, PY, PZ; + aPnt.Coord(PX, PY, PZ); - // 1. Explode compound on blocks - TopTools_MapOfShape mapShape; - Standard_Integer nbSolids = 0; + // 1. Classify the point relatively each block + Standard_Integer nearest = 2, nbFound = 0; + TopTools_DataMapOfShapeInteger mapShapeDist; TopExp_Explorer exp (aBlockOrComp, TopAbs_SOLID); for (; exp.More(); exp.Next()) { - if (mapShape.Add(exp.Current())) { - nbSolids++; - } - } + TopoDS_Shape aSolid = exp.Current(); + + if (!mapShapeDist.IsBound(aSolid)) { + Standard_Integer aDistance = 2; + + // 1.a. Classify relatively Bounding box + Standard_Real Xmin, Ymin, Zmin, Xmax, Ymax, Zmax; + Bnd_Box BB; + BRepBndLib::Add(aSolid, BB); + BB.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); + if (PX < Xmin || Xmax < PX || + PY < Ymin || Ymax < PY || + PZ < Zmin || Zmax < PZ) { + // OUT of bounding box + aDistance = 1; + } else { + // 1.b. Classify relatively the solid itself + BRepClass3d_SolidClassifier SC (aSolid, aPnt, Precision::Confusion()); + if (SC.State() == TopAbs_IN) { + aDistance = -1; + } else if (SC.State() == TopAbs_ON) { + aDistance = 0; + } else { // OUT + aDistance = 1; + } + } - mapShape.Clear(); - Standard_Integer ind = 1; - TopTools_Array1OfShape aSolids (1, nbSolids); - TColStd_Array1OfInteger aDistances (1, nbSolids); - for (exp.Init(aBlockOrComp, TopAbs_SOLID); exp.More(); exp.Next()) { - if (mapShape.Add(exp.Current())) { - TopoDS_Shape aSolid = exp.Current(); - aSolids(ind) = aSolid; + if (aDistance < nearest) { + nearest = aDistance; + aShape = aSolid; + nbFound = 1; - // 2. Classify the point relatively each block - BRepClass3d_SolidClassifier SC (aSolid, aPnt, Precision::Confusion()); - if (SC.State() == TopAbs_IN) { - aDistances(ind) = -1; - } else if (SC.State() == TopAbs_ON) { - aDistances(ind) = 0; - } else { // OUT - aDistances(ind) = 1; + // A first found block, containing the point inside, will be returned. + // It is the solution, if there are no intersecting blocks in the compound. + if (nearest == -1) break; + + } else if (aDistance == nearest) { + nbFound++; + } else { } - ind++; - } - } - // 3. Define block, containing the point or having minimum distance to it - Standard_Integer nearest = 2, nbFound = 0; - for (ind = 1; ind <= nbSolids; ind++) { - if (aDistances(ind) < nearest) { - nearest = aDistances(ind); - aShape = aSolids(ind); - nbFound = 1; - } else if (aDistances(ind) == nearest) { - nbFound++; - } else { - } + mapShapeDist.Bind(aSolid, aDistance); + } // if (!mapShapeDist.IsBound(aSolid)) } + + // 2. Define block, containing the point or having minimum distance to it if (nbFound > 1) { if (nearest == 0) { // The point is on boundary of some blocks and there are @@ -2229,9 +2578,11 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetBlockNearPoint // no blocks, having the point inside or on boundary. // We will get a nearest block Standard_Real minDist = RealLast(); - for (ind = 1; ind <= nbSolids; ind++) { - if (aDistances(ind) == 1) { - BRepExtrema_DistShapeShape aDistTool (aVert, aSolids(ind)); + TopTools_DataMapIteratorOfDataMapOfShapeInteger mapShapeDistIter (mapShapeDist); + for (; mapShapeDistIter.More(); mapShapeDistIter.Next()) { + if (mapShapeDistIter.Value() == 1) { + TopoDS_Shape aSolid = mapShapeDistIter.Key(); + BRepExtrema_DistShapeShape aDistTool (aVert, aSolid); if (!aDistTool.IsDone()) { SetErrorCode("Can not find a distance from the given point to one of blocks"); return NULL; @@ -2239,29 +2590,31 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::GetBlockNearPoint Standard_Real aDist = aDistTool.Value(); if (aDist < minDist) { minDist = aDist; - aShape = aSolids(ind); + aShape = aSolid; } } } } else { // nearest == -1 - // The point is inside some blocks. - // We will get a block with nearest center - Standard_Real minDist = RealLast(); - for (ind = 1; ind <= nbSolids; ind++) { - if (aDistances(ind) == -1) { - GProp_GProps aSystem; - BRepGProp::VolumeProperties(aSolids(ind), aSystem); - gp_Pnt aCenterMass = aSystem.CentreOfMass(); - - Standard_Real aDist = aCenterMass.Distance(aPnt); - if (aDist < minDist) { - minDist = aDist; - aShape = aSolids(ind); - } - } - } +// // The point is inside some blocks. +// // We will get a block with nearest center +// Standard_Real minDist = RealLast(); +// TopTools_DataMapIteratorOfDataMapOfShapeInteger mapShapeDistIter (mapShapeDist); +// for (; mapShapeDistIter.More(); mapShapeDistIter.Next()) { +// if (mapShapeDistIter.Value() == -1) { +// TopoDS_Shape aSolid = mapShapeDistIter.Key(); +// GProp_GProps aSystem; +// BRepGProp::VolumeProperties(aSolid, aSystem); +// gp_Pnt aCenterMass = aSystem.CentreOfMass(); +// +// Standard_Real aDist = aCenterMass.Distance(aPnt); +// if (aDist < minDist) { +// minDist = aDist; +// aShape = aSolid; +// } +// } +// } } - } + } // if (nbFound > 1) if (nbFound == 0) { SetErrorCode("There are no blocks near the given point"); @@ -2692,3 +3045,139 @@ Handle(GEOM_Object) GEOMImpl_IBlocksOperations::MakeMultiTransformation2D SetErrorCode(OK); return aCopy; } + +//============================================================================= +/*! + * Propagate + */ +//============================================================================= +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IBlocksOperations::Propagate + (Handle(GEOM_Object) theShape) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) return NULL; + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + TopTools_IndexedDataMapOfShapeListOfShape MEW; + GEOMImpl_Block6Explorer::MapShapesAndAncestors + (aShape, TopAbs_EDGE, TopAbs_WIRE, MEW); + Standard_Integer ie, nbEdges = MEW.Extent(); + + // Result + Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; + + TopTools_MapOfShape mapAcceptedEdges; + + for (ie = 1; ie <= nbEdges; ie++) { + TopoDS_Shape curE = MEW.FindKey(ie); + + if (mapAcceptedEdges.Contains(curE)) continue; + + // Build the chain + TopTools_ListOfShape currentChain; + TopTools_ListOfShape listPrevEdges; + + currentChain.Append(curE); + listPrevEdges.Append(curE); + mapAcceptedEdges.Add(curE); + + // Collect all edges pass by pass + while (listPrevEdges.Extent() > 0) { + // List of edges, added to chain on this cycle pass + TopTools_ListOfShape listCurEdges; + + // Find the next portion of edges + TopTools_ListIteratorOfListOfShape itE (listPrevEdges); + for (; itE.More(); itE.Next()) { + TopoDS_Shape anE = itE.Value(); + + // Iterate on faces, having edge + TopTools_ListIteratorOfListOfShape itW (MEW.FindFromKey(anE)); + for (; itW.More(); itW.Next()) { + TopoDS_Shape aW = itW.Value(); + TopoDS_Shape anOppE; + + BRepTools_WireExplorer aWE (TopoDS::Wire(aW)); + Standard_Integer nb = 1, found = 0; + TopTools_Array1OfShape anEdges (1,4); + for (; aWE.More(); aWE.Next(), nb++) { + if (nb > 4) { + found = 0; + break; + } + anEdges(nb) = aWE.Current(); + if (anEdges(nb).IsSame(anE)) found = nb; + } + + if (nb == 5 && found > 0) { + // Quadrangle face found, get an opposite edge + Standard_Integer opp = found + 2; + if (opp > 4) opp -= 4; + anOppE = anEdges(opp); + + if (!mapAcceptedEdges.Contains(anOppE)) { + // Add found edge to the chain + currentChain.Append(anOppE); + listCurEdges.Append(anOppE); + mapAcceptedEdges.Add(anOppE); + } + } // if (nb == 5 && found > 0) + } // for (; itF.More(); itF.Next()) + } // for (; itE.More(); itE.Next()) + + listPrevEdges = listCurEdges; + } // while (listPrevEdges.Extent() > 0) + + // Store the chain in the document + Handle(TColStd_HArray1OfInteger) anArray = + new TColStd_HArray1OfInteger (1, currentChain.Extent()); + + // Fill array of sub-shape indices + TopTools_ListIteratorOfListOfShape itSub (currentChain); + for (int index = 1; itSub.More(); itSub.Next(), ++index) { + int id = anIndices.FindIndex(itSub.Value()); + anArray->SetValue(index, id); + } + + // Add a new group object + Handle(GEOM_Object) aChain = GetEngine()->AddSubShape(theShape, anArray); + + // Set a GROUP type + aChain->SetType(GEOM_GROUP); + + // Set a sub shape type + TDF_Label aFreeLabel = aChain->GetFreeLabel(); + TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)TopAbs_EDGE); + + // Add the chain to the result + aSeq->Append(aChain); + } + + if (aSeq->IsEmpty()) { + SetErrorCode("There are no quadrangle faces in the shape"); + return aSeq; + } + + // The Propagation doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); + + // Make a Python command + TCollection_AsciiString aDescr + ("\nlistPropagationChains = IShapesOperations.Propagate("); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += (anEntry + ")"); + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr = anOldDescr + aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); + return aSeq; +} diff --git a/src/GEOMImpl/GEOMImpl_IBlocksOperations.hxx b/src/GEOMImpl/GEOMImpl_IBlocksOperations.hxx index 1ea16a053..72742f6a6 100644 --- a/src/GEOMImpl/GEOMImpl_IBlocksOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IBlocksOperations.hxx @@ -85,6 +85,8 @@ class GEOMImpl_IBlocksOperations : public GEOM_IOperations { enum BCErrorType { NOT_BLOCK, + DEGENERATED_EDGE, + SEAM_EDGE, INVALID_CONNECTION, NOT_CONNECTED, NOT_GLUED @@ -95,6 +97,9 @@ class GEOMImpl_IBlocksOperations : public GEOM_IOperations { list incriminated; }; + Standard_Boolean CheckCompoundOfBlocksOld (Handle(GEOM_Object) theCompound, + list& theErrors); + Standard_Boolean CheckCompoundOfBlocks (Handle(GEOM_Object) theCompound, list& theErrors); @@ -131,6 +136,9 @@ class GEOMImpl_IBlocksOperations : public GEOM_IOperations { const Standard_Integer theDirFace1V, const Standard_Integer theDirFace2V, const Standard_Integer theNbTimesV); + + // Build groups for Propagation of 1D hypotheses + Handle(TColStd_HSequenceOfTransient) Propagate (Handle(GEOM_Object) theShape); }; #endif diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx index ee637328b..0eac538b5 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.cxx @@ -13,6 +13,8 @@ using namespace std; #include "GEOMImpl_IShapes.hxx" #include "GEOMImpl_IGlue.hxx" +#include "GEOMImpl_Block6Explorer.hxx" + #include "GEOM_Function.hxx" #include "utilities.h" @@ -22,6 +24,7 @@ using namespace std; #include #include #include +#include #include #include @@ -31,6 +34,9 @@ using namespace std; #include #include #include +#include +#include +#include #include #include #include @@ -38,11 +44,19 @@ using namespace std; #include #include +#include +#include +#include +#include + #include #include +#include #include #include +//#include + #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC //============================================================================= @@ -207,7 +221,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) th */ //============================================================================= Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires - (list theShapes, bool isPlanarWanted) + (list theShapes, + const bool isPlanarWanted) { SetErrorCode(KO); @@ -482,6 +497,7 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces aCI.SetTolerance(theTolerance); //Compute the sub-shape value + Standard_Boolean isWarning = Standard_False; try { if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Shape driver failed to glue faces"); @@ -491,7 +507,12 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces catch (Standard_Failure) { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); SetErrorCode(aFail->GetMessageString()); - return NULL; + // to provide warning + if (!aFunction->GetValue().IsNull()) { + isWarning = Standard_True; + } else { + return NULL; + } } //Make a Python command @@ -505,6 +526,8 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces aFunction->SetDescription(aDescr); + // to provide warning + if (!isWarning) SetErrorCode(OK); SetErrorCode(OK); return aGlued; } @@ -519,6 +542,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode const Standard_Integer theShapeType, const Standard_Boolean isSorted) { +// OSD_Timer timer1, timer2, timer3, timer4; +// timer1.Start(); + SetErrorCode(KO); if (theShape.IsNull()) return NULL; @@ -556,9 +582,15 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode return aSeq; } +// timer1.Stop(); +// timer2.Start(); + if (isSorted) SortShapes(listShape); +// timer2.Stop(); +// timer3.Start(); + TopTools_IndexedMapOfShape anIndices; TopExp::MapShapes(aShape, anIndices); Handle(TColStd_HArray1OfInteger) anArray; @@ -577,6 +609,9 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode anAsciiList += ","; } +// timer3.Stop(); +// timer4.Start(); + anAsciiList.Trunc(anAsciiList.Length() - 1); anAsciiList += "]"; @@ -601,6 +636,97 @@ Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode SetErrorCode(OK); +// timer4.Stop(); + +// cout << "Explosure takes:" << endl; +// timer1.Show(); +// cout << "Sorting takes:" << endl; +// timer2.Show(); +// cout << "Sub-shapes addition takes:" << endl; +// timer3.Show(); +// cout << "Update Description takes:" << endl; +// timer4.Show(); + + return aSeq; +} + +//============================================================================= +/*! + * GetSubShapeAllIDs + */ +//============================================================================= +Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs + (Handle(GEOM_Object) theShape, + const Standard_Integer theShapeType, + const Standard_Boolean isSorted) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) return NULL; + + Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger; + TopTools_MapOfShape mapShape; + TopTools_ListOfShape listShape; + + if (aShape.ShapeType() == TopAbs_COMPOUND && + (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE || + TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID || + TopAbs_ShapeEnum(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()); + } + } + } + } else { + TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType)); + for (; exp.More(); exp.Next()) + if (mapShape.Add(exp.Current())) + listShape.Append(exp.Current()); + } + + if (listShape.IsEmpty()) { + SetErrorCode("The given shape has no sub-shapes of the requested type"); + return aSeq; + } + + if (isSorted) + SortShapes(listShape); + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + Handle(TColStd_HArray1OfInteger) anArray; + + TopTools_ListIteratorOfListOfShape itSub (listShape); + for (int index = 1; itSub.More(); itSub.Next(), ++index) { + TopoDS_Shape aValue = itSub.Value(); + aSeq->Append(anIndices.FindIndex(aValue)); + } + + //The explode doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); + + //Make a Python command + TCollection_AsciiString aDescr + ("\nlistSubShapeAllIDs = IShapesOperations.SubShapeAllIDs("); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += (anEntry + ","); + if (isSorted) + aDescr += (TCollection_AsciiString(theShapeType) + ", 1)"); + else + aDescr += (TCollection_AsciiString(theShapeType) + ", 0)"); + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr = anOldDescr + aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); return aSeq; } @@ -754,6 +880,575 @@ Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) return aReversed; } +//============================================================================= +/*! + * GetFreeFacesIDs + */ +//============================================================================= +Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs + (Handle(GEOM_Object) theShape) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + TopoDS_Shape aShape = theShape->GetValue(); + if (aShape.IsNull()) return NULL; + + Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger; + + TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks; + GEOMImpl_Block6Explorer::MapShapesAndAncestors + (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks); + + Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent(); + + if (nbFaces == 0) { + SetErrorCode("The given shape has no faces"); + return aSeq; + } + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + Standard_Integer id; + for (; ind <= nbFaces; ind++) { + if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) { + id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind)); + aSeq->Append(id); + } + } + + //The explode doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape->GetLastFunction(); + + //Make a Python command + TCollection_AsciiString aDescr ("\nlistFreeFacesIDs = IShapesOperations.GetFreeFacesIDs("); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += (anEntry + ")"); + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr = anOldDescr + aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); + return aSeq; +} + +//============================================================================= +/*! + * GetSharedShapes + */ +//============================================================================= +Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes + (Handle(GEOM_Object) theShape1, + Handle(GEOM_Object) theShape2, + const Standard_Integer theShapeType) +{ + SetErrorCode(KO); + + if (theShape1.IsNull() || theShape2.IsNull()) return NULL; + + TopoDS_Shape aShape1 = theShape1->GetValue(); + TopoDS_Shape aShape2 = theShape2->GetValue(); + + if (aShape1.IsNull() || aShape2.IsNull()) return NULL; + + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape1, anIndices); + Handle(TColStd_HArray1OfInteger) anArray; + + TopTools_IndexedMapOfShape mapShape1; + TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1); + + Handle(GEOM_Object) anObj; + Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient; + + TopTools_MapOfShape mapShape2; + TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType)); + for (; exp.More(); exp.Next()) { + TopoDS_Shape aSS = exp.Current(); + if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) { + anArray = new TColStd_HArray1OfInteger(1,1); + anArray->SetValue(1, anIndices.FindIndex(aSS)); + anObj = GetEngine()->AddSubShape(theShape1, anArray); + aSeq->Append(anObj); + } + } + + if (aSeq->IsEmpty()) { + SetErrorCode("The given shapes have no shared sub-shapes of the requested type"); + return aSeq; + } + + //The explode doesn't change object so no new function is required. + Handle(GEOM_Function) aFunction = theShape1->GetLastFunction(); + + //Make a Python command + TCollection_AsciiString aDescr + ("\nlistSharedShapes = IShapesOperations.GetSharedShapes("); + TCollection_AsciiString anEntry; + TDF_Tool::Entry(theShape1->GetEntry(), anEntry); + aDescr += (anEntry + ","); + TDF_Tool::Entry(theShape2->GetEntry(), anEntry); + aDescr += (anEntry + ","); + aDescr += TCollection_AsciiString(theShapeType) + ")"; + + TCollection_AsciiString anOldDescr = aFunction->GetDescription(); + anOldDescr = anOldDescr + aDescr; + aFunction->SetDescription(anOldDescr); + + SetErrorCode(OK); + return aSeq; +} + +//============================================================================= +/*! + * GetShapesOnPlane + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnPlane + (Handle(GEOM_Object) theShape, + const Standard_Integer theShapeType, + Handle(GEOM_Object) thePlane) +{ + SetErrorCode(KO); + + if (theShape.IsNull() || thePlane.IsNull()) return NULL; + + TopoDS_Shape aShape = theShape->GetValue(); + TopoDS_Shape aPlane = thePlane->GetValue(); + + if (aShape.IsNull() || aPlane.IsNull()) return NULL; + + TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType); + if (aShapeType != TopAbs_VERTEX && + aShapeType != TopAbs_EDGE && + aShapeType != TopAbs_FACE) { + SetErrorCode("Not implemented for the given sub-shape type"); + return NULL; + } + + //Get plane parameters + if (aPlane.IsNull() || aPlane.ShapeType() != TopAbs_FACE) return NULL; + TopoDS_Face aFace = TopoDS::Face(aPlane); + Handle(Geom_Surface) surf = BRep_Tool::Surface(aFace); + Handle(Geom_Plane) pln = Handle(Geom_Plane)::DownCast(surf); + if (pln.IsNull()) { + SetErrorCode("Not planar face given"); + return NULL; + } + const gp_Ax3 pos = pln->Position(); + const gp_Pnt loc = pos.Location(); + const gp_Dir dir = pos.Direction(); + + //Find sub-shapes on the plane + TopTools_ListOfShape listSS; + TopTools_MapOfShape mapShapes; + TopExp_Explorer exp (aShape, aShapeType); + for (; exp.More(); exp.Next()) { + TopoDS_Shape aSS = exp.Current(); + if (mapShapes.Add(aSS)) { + switch (aShapeType) { + case TopAbs_VERTEX: + { + TopoDS_Vertex aV = TopoDS::Vertex(aSS); + gp_Pnt aP = BRep_Tool::Pnt(aV); + gp_Vec vecToLoc (aP, loc); + if (vecToLoc.IsNormal(dir, Precision::Angular())) { + listSS.Append(aSS); + } + } + break; + case TopAbs_EDGE: + { + TopoDS_Edge anE = TopoDS::Edge(aSS); + Standard_Real pf, pl; + Handle(Geom_Curve) cur_curve = BRep_Tool::Curve(anE, pf, pl); + if (true) { + listSS.Append(aSS); + } + } + break; + case TopAbs_FACE: + { + TopoDS_Face aF = TopoDS::Face(aSS); + Handle(Geom_Surface) cur_surf = BRep_Tool::Surface(aF); + Handle(Geom_Plane) cur_pln = Handle(Geom_Plane)::DownCast(cur_surf); + if (!cur_pln.IsNull()) { + const gp_Ax3 cur_pos = cur_pln->Position(); + const gp_Pnt cur_loc = cur_pos.Location(); + const gp_Dir cur_dir = cur_pos.Direction(); + gp_Vec vecToLoc (cur_loc, loc); + if (vecToLoc.IsNormal(dir, Precision::Angular()) && + cur_dir.IsParallel(dir, Precision::Angular())) { + listSS.Append(aSS); + } + } + } + break; + default: + break; + } + } + } + + //Fill array of indices + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + Handle(TColStd_HArray1OfInteger) anArray = + new TColStd_HArray1OfInteger (1, listSS.Extent()); + TopTools_ListIteratorOfListOfShape itSub (listSS); + for (int index = 1; itSub.More(); itSub.Next(), ++index) { + int id = anIndices.FindIndex(itSub.Value()); + anArray->SetValue(index, id); + } + + //Add a new group object + Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theShape, anArray); + + //Set a GROUP type + aGroup->SetType(GEOM_GROUP); + + //Set a sub shape type + TDF_Label aFreeLabel = aGroup->GetFreeLabel(); + TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType); + + //Make a Python command + TCollection_AsciiString anEntry, aDescr; + TDF_Tool::Entry(aGroup->GetEntry(), anEntry); + aDescr += anEntry; + aDescr += " = IShapesOperations.GetShapesOnPlane("; + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += anEntry + TCollection_AsciiString(theShapeType) + ","; + TDF_Tool::Entry(thePlane->GetEntry(), anEntry); + aDescr += anEntry + ")"; + + Handle(GEOM_Function) aFunction = aGroup->GetFunction(1); + aFunction->SetDescription(aDescr); + + SetErrorCode(OK); + return aGroup; +} + +//============================================================================= +/*! + * GetShapesOnCylinder + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnCylinder + (Handle(GEOM_Object) theShape, + const Standard_Integer theShapeType, + Handle(GEOM_Object) theAxis, + const Standard_Real theRadius) +{ + SetErrorCode(KO); + + if (theShape.IsNull() || theAxis.IsNull()) return NULL; + + TopoDS_Shape aShape = theShape->GetValue(); + TopoDS_Shape anAxis = theAxis->GetValue(); + + if (aShape.IsNull() || anAxis.IsNull()) return NULL; + + TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType); + if (aShapeType != TopAbs_VERTEX && + aShapeType != TopAbs_EDGE && + aShapeType != TopAbs_FACE) { + SetErrorCode("Not implemented for the given sub-shape type"); + return NULL; + } + + //Axis of the cylinder + if (anAxis.ShapeType() != TopAbs_EDGE) { + SetErrorCode("Not an edge given for the axis"); + return NULL; + } + TopoDS_Edge anEdge = TopoDS::Edge(anAxis); + TopoDS_Vertex V1, V2; + TopExp::Vertices(anEdge, V1, V2, Standard_True); + if (V1.IsNull() || V2.IsNull()) { + SetErrorCode("Bad edge given for the axis"); + return NULL; + } + gp_Pnt loc = BRep_Tool::Pnt(V1); + gp_Vec aVec (loc, BRep_Tool::Pnt(V2)); + gp_Dir dir (aVec); + gp_Lin aLin (loc, aVec); + + //Find sub-shapes on the cylinder + TopTools_ListOfShape listSS; + TopTools_MapOfShape mapShapes; + TopExp_Explorer exp (aShape, aShapeType); + for (; exp.More(); exp.Next()) { + TopoDS_Shape aSS = exp.Current(); + if (mapShapes.Add(aSS)) { + switch (aShapeType) { + case TopAbs_VERTEX: + { + TopoDS_Vertex aV = TopoDS::Vertex(aSS); + gp_Pnt aP = BRep_Tool::Pnt(aV); + if (Abs(aLin.Distance(aP) - theRadius) < Precision::Confusion()) { + listSS.Append(aSS); + } + } + break; + case TopAbs_EDGE: + { + TopoDS_Edge anE = TopoDS::Edge(aSS); + Standard_Real pf, pl; + Handle(Geom_Curve) cur_curve = BRep_Tool::Curve(anE, pf, pl); + if (true) { + listSS.Append(aSS); + } + } + break; + case TopAbs_FACE: + { + TopoDS_Face aF = TopoDS::Face(aSS); + Handle(Geom_Surface) cur_surf = BRep_Tool::Surface(aF); + Handle(Geom_CylindricalSurface) cur_cyl = + Handle(Geom_CylindricalSurface)::DownCast(cur_surf); + if (!cur_cyl.IsNull()) { + const gp_Ax3 cur_pos = cur_cyl->Position(); + const gp_Pnt cur_loc = cur_pos.Location(); + const gp_Dir cur_dir = cur_pos.Direction(); + const Standard_Real cur_rad = cur_cyl->Radius(); + gp_Vec vecToLoc (cur_loc, loc); + if (vecToLoc.IsParallel(dir, Precision::Angular()) && + cur_dir.IsParallel(dir, Precision::Angular()) && + Abs(cur_rad - theRadius) < Precision::Confusion()) { + listSS.Append(aSS); + } + } + } + break; + default: + break; + } + } + } + + //Fill array of indices + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + Handle(TColStd_HArray1OfInteger) anArray = + new TColStd_HArray1OfInteger (1, listSS.Extent()); + TopTools_ListIteratorOfListOfShape itSub (listSS); + for (int index = 1; itSub.More(); itSub.Next(), ++index) { + int id = anIndices.FindIndex(itSub.Value()); + anArray->SetValue(index, id); + } + + //Add a new group object + Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theShape, anArray); + + //Set a GROUP type + aGroup->SetType(GEOM_GROUP); + + //Set a sub shape type + TDF_Label aFreeLabel = aGroup->GetFreeLabel(); + TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType); + + //Make a Python command + TCollection_AsciiString anEntry, aDescr; + TDF_Tool::Entry(aGroup->GetEntry(), anEntry); + aDescr += anEntry; + aDescr += " = IShapesOperations.GetShapesOnCylinder("; + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += anEntry + TCollection_AsciiString(theShapeType) + ","; + TDF_Tool::Entry(theAxis->GetEntry(), anEntry); + aDescr += anEntry + TCollection_AsciiString(theRadius) + ")"; + + Handle(GEOM_Function) aFunction = aGroup->GetFunction(1); + aFunction->SetDescription(aDescr); + + SetErrorCode(OK); + return aGroup; +} + +//============================================================================= +/*! + * GetShapesOnSphere + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnSphere + (Handle(GEOM_Object) theShape, + const Standard_Integer theShapeType, + Handle(GEOM_Object) theCenter, + const Standard_Real theRadius) +{ + SetErrorCode(KO); + + if (theShape.IsNull() || theCenter.IsNull()) return NULL; + + TopoDS_Shape aShape = theShape->GetValue(); + TopoDS_Shape aCenter = theCenter->GetValue(); + + if (aShape.IsNull() || aCenter.IsNull()) return NULL; + + TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType); + if (aShapeType != TopAbs_VERTEX && + aShapeType != TopAbs_EDGE && + aShapeType != TopAbs_FACE) { + SetErrorCode("Not implemented for the given sub-shape type"); + return NULL; + } + + //Center of the sphere + if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL; + gp_Pnt aC = BRep_Tool::Pnt(TopoDS::Vertex(aCenter)); + + //Find sub-shapes on the sphere + TopTools_ListOfShape listSS; + TopTools_MapOfShape mapShapes; + TopExp_Explorer exp (aShape, aShapeType); + for (; exp.More(); exp.Next()) { + TopoDS_Shape aSS = exp.Current(); + if (mapShapes.Add(aSS)) { + switch (aShapeType) { + case TopAbs_VERTEX: + { + TopoDS_Vertex aV = TopoDS::Vertex(aSS); + gp_Pnt aP = BRep_Tool::Pnt(aV); + if (Abs(aP.Distance(aC) - theRadius) < Precision::Confusion()) { + listSS.Append(aSS); + } + } + break; + case TopAbs_EDGE: + { + TopoDS_Edge anE = TopoDS::Edge(aSS); + Standard_Real pf, pl; + Handle(Geom_Curve) cur_curve = BRep_Tool::Curve(anE, pf, pl); + if (true) { + listSS.Append(aSS); + } + } + break; + case TopAbs_FACE: + { + TopoDS_Face aF = TopoDS::Face(aSS); + Handle(Geom_Surface) cur_surf = BRep_Tool::Surface(aF); + Handle(Geom_SphericalSurface) cur_sph = + Handle(Geom_SphericalSurface)::DownCast(cur_surf); + if (!cur_sph.IsNull()) { + const gp_Ax3 cur_pos = cur_sph->Position(); + const gp_Pnt cur_loc = cur_pos.Location(); + const Standard_Real cur_rad = cur_sph->Radius(); + if (cur_loc.Distance(aC) < Precision::Confusion() && + Abs(cur_rad - theRadius) < Precision::Confusion()) { + listSS.Append(aSS); + } + } + } + break; + default: + break; + } + } + } + + //Fill array of indices + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aShape, anIndices); + + Handle(TColStd_HArray1OfInteger) anArray = + new TColStd_HArray1OfInteger (1, listSS.Extent()); + TopTools_ListIteratorOfListOfShape itSub (listSS); + for (int index = 1; itSub.More(); itSub.Next(), ++index) { + int id = anIndices.FindIndex(itSub.Value()); + anArray->SetValue(index, id); + } + + //Add a new group object + Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theShape, anArray); + + //Set a GROUP type + aGroup->SetType(GEOM_GROUP); + + //Set a sub shape type + TDF_Label aFreeLabel = aGroup->GetFreeLabel(); + TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType); + + //Make a Python command + TCollection_AsciiString anEntry, aDescr; + TDF_Tool::Entry(aGroup->GetEntry(), anEntry); + aDescr += anEntry; + aDescr += " = IShapesOperations.GetShapesOnSphere("; + TDF_Tool::Entry(theShape->GetEntry(), anEntry); + aDescr += anEntry + TCollection_AsciiString(theShapeType) + ","; + TDF_Tool::Entry(theCenter->GetEntry(), anEntry); + aDescr += anEntry + TCollection_AsciiString(theRadius) + ")"; + + Handle(GEOM_Function) aFunction = aGroup->GetFunction(1); + aFunction->SetDescription(aDescr); + + SetErrorCode(OK); + return aGroup; +} + +//============================================================================= +/*! + * GetInPlace + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace + (Handle(GEOM_Object) theShapeWhere, + Handle(GEOM_Object) theShapeWhat) +{ + SetErrorCode(KO); + + if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL; + + TopoDS_Shape aWhere = theShapeWhere->GetValue(); + TopoDS_Shape aWhat = theShapeWhat->GetValue(); + + if (aWhere.IsNull() || aWhat.IsNull()) return NULL; + + //Fill array of indices + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aWhere, anIndices); + +// Handle(TColStd_HArray1OfInteger) anArray = +// new TColStd_HArray1OfInteger (1, listSS.Extent()); +// TopTools_ListIteratorOfListOfShape itSub (listSS); +// for (int index = 1; itSub.More(); itSub.Next(), ++index) { +// int id = anIndices.FindIndex(itSub.Value()); +// anArray->SetValue(index, id); +// } +// +// //Add a new group object +// Handle(GEOM_Object) aGroup = GetEngine()->AddSubShape(theShape, anArray); +// +// //Set a GROUP type +// aGroup->SetType(GEOM_GROUP); +// +// //Set a sub shape type +// TDF_Label aFreeLabel = aGroup->GetFreeLabel(); +// TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)theShapeType); +// +// //Make a Python command +// TCollection_AsciiString anEntry, aDescr; +// TDF_Tool::Entry(aGroup->GetEntry(), anEntry); +// aDescr += anEntry; +// aDescr += " = IShapesOperations.GetInPlace("; +// TDF_Tool::Entry(theShapeWhere->GetEntry(), anEntry); +// aDescr += anEntry + ","; +// TDF_Tool::Entry(theShapeWhat->GetEntry(), anEntry); +// aDescr += anEntry + ")"; +// +// Handle(GEOM_Function) aFunction = aGroup->GetFunction(1); +// aFunction->SetDescription(aDescr); + +// SetErrorCode(OK); +// return aGroup; + SetErrorCode("Not implemented"); + return NULL; +} + //======================================================================= //function : SortShapes diff --git a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx index 9ae51717a..469f88541 100644 --- a/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx +++ b/src/GEOMImpl/GEOMImpl_IShapesOperations.hxx @@ -6,6 +6,7 @@ #include #include +#include #include @@ -23,9 +24,10 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations { Handle(GEOM_Object) MakeWire (list theEdgesAndWires); - Handle(GEOM_Object) MakeFace (Handle(GEOM_Object) theWire, bool isPlanarWanted); + Handle(GEOM_Object) MakeFace (Handle(GEOM_Object) theWire, const bool isPlanarWanted); - Handle(GEOM_Object) MakeFaceWires (list theWires, bool isPlanarWanted); + Handle(GEOM_Object) MakeFaceWires (list theWires, + const bool isPlanarWanted); Handle(GEOM_Object) MakeShell (list theShapes); @@ -42,6 +44,10 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations { const Standard_Integer theShapeType, const Standard_Boolean isSorted); + Handle(TColStd_HSequenceOfInteger) SubShapeAllIDs (Handle(GEOM_Object) theShape, + const Standard_Integer theShapeType, + const Standard_Boolean isSorted); + Handle(GEOM_Object) GetSubShape (Handle(GEOM_Object) theMainShape, const Standard_Integer theID); @@ -50,6 +56,29 @@ class GEOMImpl_IShapesOperations : public GEOM_IOperations { Handle(GEOM_Object) ReverseShape(Handle(GEOM_Object) theShapes); + Handle(TColStd_HSequenceOfInteger) GetFreeFacesIDs (Handle(GEOM_Object) theShape); + + Handle(TColStd_HSequenceOfTransient) GetSharedShapes (Handle(GEOM_Object) theShape1, + Handle(GEOM_Object) theShape2, + const Standard_Integer theShapeType); + + Handle(GEOM_Object) GetShapesOnPlane (Handle(GEOM_Object) theShape, + const Standard_Integer theShapeType, + Handle(GEOM_Object) thePlane); + + Handle(GEOM_Object) GetShapesOnCylinder (Handle(GEOM_Object) theShape, + const Standard_Integer theShapeType, + Handle(GEOM_Object) theAxis, + const Standard_Real theRadius); + + Handle(GEOM_Object) GetShapesOnSphere (Handle(GEOM_Object) theShape, + const Standard_Integer theShapeType, + Handle(GEOM_Object) theCenter, + const Standard_Real theRadius); + + Handle(GEOM_Object) GetInPlace (Handle(GEOM_Object) theShapeWhere, + Handle(GEOM_Object) theShapeWhat); + static void SortShapes (TopTools_ListOfShape& SL); private: diff --git a/src/GEOM_I/GEOM_IBlocksOperations_i.cc b/src/GEOM_I/GEOM_IBlocksOperations_i.cc index a5aeb7ee8..58f0f7c0e 100644 --- a/src/GEOM_I/GEOM_IBlocksOperations_i.cc +++ b/src/GEOM_I/GEOM_IBlocksOperations_i.cc @@ -657,6 +657,12 @@ CORBA::Boolean GEOM_IBlocksOperations_i::CheckCompoundOfBlocks case GEOMImpl_IBlocksOperations::NOT_BLOCK: anError->error = GEOM::GEOM_IBlocksOperations::NOT_BLOCK; break; + case GEOMImpl_IBlocksOperations::DEGENERATED_EDGE: + anError->error = GEOM::GEOM_IBlocksOperations::DEGENERATED_EDGE; + break; + case GEOMImpl_IBlocksOperations::SEAM_EDGE: + anError->error = GEOM::GEOM_IBlocksOperations::SEAM_EDGE; + break; case GEOMImpl_IBlocksOperations::INVALID_CONNECTION: anError->error = GEOM::GEOM_IBlocksOperations::INVALID_CONNECTION; break; @@ -720,6 +726,12 @@ char* GEOM_IBlocksOperations_i::PrintBCErrors case GEOM::GEOM_IBlocksOperations::NOT_BLOCK: errStruct.error = GEOMImpl_IBlocksOperations::NOT_BLOCK; break; + case GEOM::GEOM_IBlocksOperations::DEGENERATED_EDGE: + errStruct.error = GEOMImpl_IBlocksOperations::DEGENERATED_EDGE; + break; + case GEOM::GEOM_IBlocksOperations::SEAM_EDGE: + errStruct.error = GEOMImpl_IBlocksOperations::SEAM_EDGE; + break; case GEOM::GEOM_IBlocksOperations::INVALID_CONNECTION: errStruct.error = GEOMImpl_IBlocksOperations::INVALID_CONNECTION; break; @@ -937,3 +949,37 @@ GEOM::GEOM_Object_ptr GEOM_IBlocksOperations_i::MakeMultiTransformation2D return GetObject(anObject); } + +//============================================================================= +/*! + * Propagate + */ +//============================================================================= +GEOM::ListOfGO* GEOM_IBlocksOperations_i::Propagate (GEOM::GEOM_Object_ptr theShape) +{ + GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; + + //Set a not done flag + GetOperations()->SetNotDone(); + + if (theShape == NULL) return aSeq._retn(); + + //Get the reference Shape + Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject + (theShape->GetStudyID(), theShape->GetEntry()); + + if (aShape.IsNull()) return aSeq._retn(); + + //Get the Propagation chains + Handle(TColStd_HSequenceOfTransient) aHSeq = + GetOperations()->Propagate(aShape); + if (!GetOperations()->IsDone() || aHSeq.IsNull()) + return aSeq._retn(); + + Standard_Integer aLength = aHSeq->Length(); + aSeq->length(aLength); + for (Standard_Integer i = 1; i <= aLength; i++) + aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i))); + + return aSeq._retn(); +} diff --git a/src/GEOM_I/GEOM_IBlocksOperations_i.hh b/src/GEOM_I/GEOM_IBlocksOperations_i.hh index 32c5085da..ff06a1c64 100644 --- a/src/GEOM_I/GEOM_IBlocksOperations_i.hh +++ b/src/GEOM_I/GEOM_IBlocksOperations_i.hh @@ -119,6 +119,9 @@ class GEOM_IBlocksOperations_i : const CORBA::Long theDirFace2V, const CORBA::Long theNbTimesV); + // Build groups for Propagation of 1D hypotheses + GEOM::ListOfGO* Propagate (GEOM::GEOM_Object_ptr theShape); + ::GEOMImpl_IBlocksOperations* GetOperations() { return (::GEOMImpl_IBlocksOperations*)GetImpl(); } }; diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.cc b/src/GEOM_I/GEOM_IShapesOperations_i.cc index 4f8236d4a..9bfdf7f6b 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.cc +++ b/src/GEOM_I/GEOM_IShapesOperations_i.cc @@ -108,7 +108,8 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeWire */ //============================================================================= GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFace - (GEOM::GEOM_Object_ptr theWire, CORBA::Boolean isPlanarWanted) + (GEOM::GEOM_Object_ptr theWire, + const CORBA::Boolean isPlanarWanted) { GEOM::GEOM_Object_var aGEOMObject; @@ -138,7 +139,7 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFace //============================================================================= GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeFaceWires (const GEOM::ListOfGO& theWires, - CORBA::Boolean isPlanarWanted) + const CORBA::Boolean isPlanarWanted) { GEOM::GEOM_Object_var aGEOMObject; @@ -323,10 +324,12 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::MakeGlueFaces if (aShape.IsNull()) return aGEOMObject._retn(); - //Perform the glueing + //Perform the gluing Handle(GEOM_Object) anObject = GetOperations()->MakeGlueFaces(aShape, theTolerance); - if (!GetOperations()->IsDone() || anObject.IsNull()) + //if (!GetOperations()->IsDone() || anObject.IsNull()) + // to allow warning + if (anObject.IsNull()) return aGEOMObject._retn(); return GetObject(anObject); @@ -342,10 +345,15 @@ GEOM::ListOfGO* GEOM_IShapesOperations_i::MakeExplode (GEOM::GEOM_Object_ptr the const CORBA::Boolean isSorted) { GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; - if (theShape == NULL) return aSeq._retn(); - Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject(theShape->GetStudyID(), theShape->GetEntry()); - Handle(TColStd_HSequenceOfTransient) aHSeq = GetOperations()->MakeExplode(aShape, theShapeType, isSorted); - if (!GetOperations()->IsDone() || aHSeq.IsNull()) return aSeq._retn(); + if (theShape == NULL) return aSeq._retn(); + + Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject + (theShape->GetStudyID(), theShape->GetEntry()); + + Handle(TColStd_HSequenceOfTransient) aHSeq = + GetOperations()->MakeExplode(aShape, theShapeType, isSorted); + if (!GetOperations()->IsDone() || aHSeq.IsNull()) + return aSeq._retn(); Standard_Integer aLength = aHSeq->Length(); aSeq->length(aLength); @@ -355,6 +363,33 @@ GEOM::ListOfGO* GEOM_IShapesOperations_i::MakeExplode (GEOM::GEOM_Object_ptr the return aSeq._retn(); } +//============================================================================= +/*! + * SubShapeAllIDs + */ +//============================================================================= +GEOM::ListOfLong* GEOM_IShapesOperations_i::SubShapeAllIDs (GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + const CORBA::Boolean isSorted) +{ + GEOM::ListOfLong_var aSeq = new GEOM::ListOfLong; + if (theShape == NULL) return aSeq._retn(); + + Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject + (theShape->GetStudyID(), theShape->GetEntry()); + + Handle(TColStd_HSequenceOfInteger) aHSeq = + GetOperations()->SubShapeAllIDs(aShape, theShapeType, isSorted); + if (!GetOperations()->IsDone() || aHSeq.IsNull()) return aSeq._retn(); + + Standard_Integer aLength = aHSeq->Length(); + aSeq->length(aLength); + for (Standard_Integer i = 1; i <= aLength; i++) + aSeq[i-1] = aHSeq->Value(i); + + return aSeq._retn(); +} + //============================================================================= /*! * GetSubShape @@ -422,7 +457,7 @@ CORBA::Long GEOM_IShapesOperations_i::NumberOfEdges (GEOM::GEOM_Object_ptr theSh //============================================================================= /*! - * ReverseOrientation + * ChangeOrientation */ //============================================================================= GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::ChangeOrientation @@ -449,3 +484,207 @@ GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::ChangeOrientation return GetObject(anObject); } +//============================================================================= +/*! + * GetFreeFacesIDs + */ +//============================================================================= +GEOM::ListOfLong* GEOM_IShapesOperations_i::GetFreeFacesIDs (GEOM::GEOM_Object_ptr theShape) +{ + GEOM::ListOfLong_var aSeq = new GEOM::ListOfLong; + if (theShape == NULL) return aSeq._retn(); + + Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject + (theShape->GetStudyID(), theShape->GetEntry()); + + Handle(TColStd_HSequenceOfInteger) aHSeq = + GetOperations()->GetFreeFacesIDs(aShape); + if (!GetOperations()->IsDone() || aHSeq.IsNull()) return aSeq._retn(); + + Standard_Integer aLength = aHSeq->Length(); + aSeq->length(aLength); + for (Standard_Integer i = 1; i <= aLength; i++) + aSeq[i-1] = aHSeq->Value(i); + + return aSeq._retn(); +} + +//============================================================================= +/*! + * GetSharedShapes + */ +//============================================================================= +GEOM::ListOfGO* GEOM_IShapesOperations_i::GetSharedShapes + (GEOM::GEOM_Object_ptr theShape1, + GEOM::GEOM_Object_ptr theShape2, + const CORBA::Long theShapeType) +{ + GEOM::ListOfGO_var aSeq = new GEOM::ListOfGO; + if (theShape1 == NULL || + theShape2 == NULL) return aSeq._retn(); + + Handle(GEOM_Object) aShape1 = GetOperations()->GetEngine()->GetObject + (theShape1->GetStudyID(), theShape1->GetEntry()); + Handle(GEOM_Object) aShape2 = GetOperations()->GetEngine()->GetObject + (theShape2->GetStudyID(), theShape2->GetEntry()); + + if (aShape1.IsNull() || + aShape2.IsNull()) return aSeq._retn(); + + Handle(TColStd_HSequenceOfTransient) aHSeq = + GetOperations()->GetSharedShapes(aShape1, aShape2, theShapeType); + if (!GetOperations()->IsDone() || aHSeq.IsNull()) + return aSeq._retn(); + + Standard_Integer aLength = aHSeq->Length(); + aSeq->length(aLength); + for (Standard_Integer i = 1; i <= aLength; i++) + aSeq[i-1] = GetObject(Handle(GEOM_Object)::DownCast(aHSeq->Value(i))); + + return aSeq._retn(); +} + +//============================================================================= +/*! + * GetShapesOnPlane + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetShapesOnPlane + (GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + GEOM::GEOM_Object_ptr thePlane) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + if (theShape == NULL || + thePlane == NULL) return aGEOMObject._retn(); + + //Get the reference objects + Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject + (theShape->GetStudyID(), theShape->GetEntry()); + Handle(GEOM_Object) aPlane = GetOperations()->GetEngine()->GetObject + (thePlane->GetStudyID(), thePlane->GetEntry()); + + if (aShape.IsNull() || + aPlane.IsNull()) return aGEOMObject._retn(); + + //Get Shapes On Plane + Handle(GEOM_Object) anObject = + GetOperations()->GetShapesOnPlane(aShape, theShapeType, aPlane); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + +//============================================================================= +/*! + * GetShapesOnCylinder + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetShapesOnCylinder + (GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + GEOM::GEOM_Object_ptr theAxis, + const CORBA::Double theRadius) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + if (theShape == NULL || + theAxis == NULL) return aGEOMObject._retn(); + + //Get the reference objects + Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject + (theShape->GetStudyID(), theShape->GetEntry()); + Handle(GEOM_Object) anAxis = GetOperations()->GetEngine()->GetObject + (theAxis->GetStudyID(), theAxis->GetEntry()); + + if (aShape.IsNull() || + anAxis.IsNull()) return aGEOMObject._retn(); + + //Get Shapes On Cylinder + Handle(GEOM_Object) anObject = + GetOperations()->GetShapesOnCylinder(aShape, theShapeType, anAxis, theRadius); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + +//============================================================================= +/*! + * GetShapesOnSphere + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetShapesOnSphere + (GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + GEOM::GEOM_Object_ptr theCenter, + const CORBA::Double theRadius) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + if (theShape == NULL || + theCenter == NULL) return aGEOMObject._retn(); + + //Get the reference objects + Handle(GEOM_Object) aShape = GetOperations()->GetEngine()->GetObject + (theShape->GetStudyID(), theShape->GetEntry()); + Handle(GEOM_Object) aCenter = GetOperations()->GetEngine()->GetObject + (theCenter->GetStudyID(), theCenter->GetEntry()); + + if (aShape.IsNull() || + aCenter.IsNull()) return aGEOMObject._retn(); + + //Get Shapes On Sphere + Handle(GEOM_Object) anObject = + GetOperations()->GetShapesOnSphere(aShape, theShapeType, aCenter, theRadius); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} + +//============================================================================= +/*! + * GetInPlace + */ +//============================================================================= +GEOM::GEOM_Object_ptr GEOM_IShapesOperations_i::GetInPlace + (GEOM::GEOM_Object_ptr theShapeWhere, + GEOM::GEOM_Object_ptr theShapeWhat) +{ + GEOM::GEOM_Object_var aGEOMObject; + + //Set a not done flag + GetOperations()->SetNotDone(); + + if (theShapeWhere == NULL || + theShapeWhat == NULL) return aGEOMObject._retn(); + + //Get the reference objects + Handle(GEOM_Object) aShapeWhere = GetOperations()->GetEngine()->GetObject + (theShapeWhere->GetStudyID(), theShapeWhere->GetEntry()); + Handle(GEOM_Object) aShapeWhat = GetOperations()->GetEngine()->GetObject + (theShapeWhat->GetStudyID(), theShapeWhat->GetEntry()); + + if (aShapeWhere.IsNull() || + aShapeWhat.IsNull()) return aGEOMObject._retn(); + + //Get Shapes in place of aShapeWhat + Handle(GEOM_Object) anObject = + GetOperations()->GetInPlace(aShapeWhere, aShapeWhat); + if (!GetOperations()->IsDone() || anObject.IsNull()) + return aGEOMObject._retn(); + + return GetObject(anObject); +} diff --git a/src/GEOM_I/GEOM_IShapesOperations_i.hh b/src/GEOM_I/GEOM_IShapesOperations_i.hh index 4a63bb1f5..dea3af329 100644 --- a/src/GEOM_I/GEOM_IShapesOperations_i.hh +++ b/src/GEOM_I/GEOM_IShapesOperations_i.hh @@ -16,7 +16,8 @@ class GEOM_IShapesOperations_i : public virtual GEOM_IOperations_i { public: - GEOM_IShapesOperations_i (PortableServer::POA_ptr thePOA, GEOM::GEOM_Gen_ptr theEngine, + GEOM_IShapesOperations_i (PortableServer::POA_ptr thePOA, + GEOM::GEOM_Gen_ptr theEngine, ::GEOMImpl_IShapesOperations* theImpl); ~GEOM_IShapesOperations_i(); @@ -26,10 +27,10 @@ class GEOM_IShapesOperations_i : GEOM::GEOM_Object_ptr MakeWire (const GEOM::ListOfGO& theEdgesAndWires); GEOM::GEOM_Object_ptr MakeFace (GEOM::GEOM_Object_ptr theWire, - CORBA::Boolean isPlanarWanted); + const CORBA::Boolean isPlanarWanted); GEOM::GEOM_Object_ptr MakeFaceWires (const GEOM::ListOfGO& theWires, - CORBA::Boolean isPlanarWanted); + const CORBA::Boolean isPlanarWanted); GEOM::GEOM_Object_ptr MakeShell (const GEOM::ListOfGO& theFacesAndShells); @@ -43,8 +44,12 @@ class GEOM_IShapesOperations_i : const CORBA::Double theTolerance); GEOM::ListOfGO* MakeExplode (GEOM::GEOM_Object_ptr theShape, - const CORBA::Long theShapeType, - const CORBA::Boolean isSorted); + const CORBA::Long theShapeType, + const CORBA::Boolean isSorted); + + GEOM::ListOfLong* SubShapeAllIDs (GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + const CORBA::Boolean isSorted); GEOM::GEOM_Object_ptr GetSubShape (GEOM::GEOM_Object_ptr theMainShape, const CORBA::Long theID); @@ -54,6 +59,29 @@ class GEOM_IShapesOperations_i : GEOM::GEOM_Object_ptr ChangeOrientation (GEOM::GEOM_Object_ptr theShape); + GEOM::ListOfLong* GetFreeFacesIDs (GEOM::GEOM_Object_ptr theShape); + + GEOM::ListOfGO* GetSharedShapes (GEOM::GEOM_Object_ptr theShape1, + GEOM::GEOM_Object_ptr theShape2, + const CORBA::Long theShapeType); + + GEOM::GEOM_Object_ptr GetShapesOnPlane (GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + GEOM::GEOM_Object_ptr thePlane); + + GEOM::GEOM_Object_ptr GetShapesOnCylinder (GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + GEOM::GEOM_Object_ptr theAxis, + const CORBA::Double theRadius); + + GEOM::GEOM_Object_ptr GetShapesOnSphere (GEOM::GEOM_Object_ptr theShape, + const CORBA::Long theShapeType, + GEOM::GEOM_Object_ptr theCenter, + const CORBA::Double theRadius); + + GEOM::GEOM_Object_ptr GetInPlace (GEOM::GEOM_Object_ptr theShapeWhere, + GEOM::GEOM_Object_ptr theShapeWhat); + ::GEOMImpl_IShapesOperations* GetOperations() { return (::GEOMImpl_IShapesOperations*)GetImpl(); } }; diff --git a/src/GEOM_SWIG/batchmode_geompy.py b/src/GEOM_SWIG/batchmode_geompy.py index ab0a90fe8..38f410ae6 100644 --- a/src/GEOM_SWIG/batchmode_geompy.py +++ b/src/GEOM_SWIG/batchmode_geompy.py @@ -408,12 +408,24 @@ def SubShapeAll(aShape, aType): print "MakeExplode : ", ShapesOp.GetErrorCode() return ListObj +def SubShapeAllIDs(aShape, aType): + ListObj = ShapesOp.SubShapeAllIDs(aShape,aType,0) + if ShapesOp.IsDone() == 0: + print "SubShapeAllIDs : ", ShapesOp.GetErrorCode() + return ListObj + def SubShapeAllSorted(aShape,aType): ListObj = ShapesOp.MakeExplode(aShape,aType,1) if ShapesOp.IsDone() == 0: print "MakeExplode : ", ShapesOp.GetErrorCode() return ListObj +def SubShapeAllSortedIDs(aShape, aType): + ListIDs = ShapesOp.SubShapeAllIDs(aShape,aType,1) + if ShapesOp.IsDone() == 0: + print "SubShapeAllSortedIDs : ", ShapesOp.GetErrorCode() + return ListObj + # Obtain a compound of sub-shapes of , # selected by they indices in list of all sub-shapes of type def SubShape(aShape, aType, ListOfInd): diff --git a/src/GEOM_SWIG/geompy.py b/src/GEOM_SWIG/geompy.py index b2bc785ac..b7b8d4658 100644 --- a/src/GEOM_SWIG/geompy.py +++ b/src/GEOM_SWIG/geompy.py @@ -793,6 +793,17 @@ def SubShapeAll(aShape, aType): print "MakeExplode : ", ShapesOp.GetErrorCode() return ListObj +# * Explode a shape on subshapes of a given type. +# * \param theShape Shape to be exploded. +# * \param theShapeType Type of sub-shapes to be retrieved. +# * \return List of IDs of sub-shapes. +# +def SubShapeAllIDs(aShape, aType): + ListObj = ShapesOp.SubShapeAllIDs(aShape,aType,0) + if ShapesOp.IsDone() == 0: + print "SubShapeAllIDs : ", ShapesOp.GetErrorCode() + return ListObj + # * Explode a shape on subshapes of a given type. # * Sub-shapes will be sorted by coordinates of their gravity centers. # * \param theShape Shape to be exploded. @@ -807,6 +818,18 @@ def SubShapeAllSorted(aShape, aType): print "MakeExplode : ", ShapesOp.GetErrorCode() return ListObj +# * Explode a shape on subshapes of a given type. +# * Sub-shapes will be sorted by coordinates of their gravity centers. +# * \param theShape Shape to be exploded. +# * \param theShapeType Type of sub-shapes to be retrieved. +# * \return List of IDs of sub-shapes. +# +def SubShapeAllSortedIDs(aShape, aType): + ListIDs = ShapesOp.SubShapeAllIDs(aShape,aType,1) + if ShapesOp.IsDone() == 0: + print "SubShapeAllSortedIDs : ", ShapesOp.GetErrorCode() + return ListObj + # * Obtain a compound of sub-shapes of , # * selected by they indices in list of all sub-shapes of type . # * Each index is in range [1, Nb_Sub-Shapes_Of_Given_Type] -- 2.39.2