+ // The GetShapesOnShape() doesn't change object so no new function is required.
+ Handle(GEOM_Function) aFunction =
+ GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
+
+ // Make a Python command
+ GEOM::TPythonDump(aFunction)
+ << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
+ << theCheckShape << ", "
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : GetShapesOnShape
+/*!
+ * \brief Find subshapes complying with given status about surface
+ * \param theCheckShape - the shape to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfTransient)
+ GEOMImpl_IShapesOperations::GetShapesOnShape
+ (const Handle(GEOM_Object)& theCheckShape,
+ const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ GEOMAlgo_State theState)
+{
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
+ return NULL;
+
+ // Find objects by indices
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
+
+ if ( aSeq.IsNull() || aSeq->IsEmpty() )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction)
+ << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
+ << theCheckShape << ", "
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=======================================================================
+//function : GetShapesOnShapeAsCompound
+//=======================================================================
+Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
+ (const Handle(GEOM_Object)& theCheckShape,
+ const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ GEOMAlgo_State theState)
+{
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
+
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
+ return NULL;
+
+ // Find objects by indices
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
+
+ if ( aSeq.IsNull() || aSeq->IsEmpty() )
+ return NULL;
+
+ TopoDS_Compound aCompound;
+ BRep_Builder B;
+ B.MakeCompound(aCompound);
+ int i = 1;
+ for(; i<=aSeq->Length(); i++) {
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
+ TopoDS_Shape aShape_i = anObj->GetValue();
+ B.Add(aCompound,aShape_i);
+ }
+
+ //Add a new result object
+ Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
+ Handle(GEOM_Function) aFunction =
+ aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
+ aFunction->SetValue(aCompound);
+
+ GEOM::TPythonDump(aFunction)
+ << aRes << " = geompy.GetShapesOnShapeAsCompound("
+ << theCheckShape << ", "
+ << theShape << ", "
+ << TopAbs_ShapeEnum(theShapeType) << ", "
+ << theState << ")";
+
+ SetErrorCode(OK);
+
+ return aRes;
+}
+
+//=======================================================================
+//function : getShapesOnSurfaceIDs
+ /*!
+ * \brief Find IDs of subshapes complying with given status about surface
+ * \param theSurface - the surface to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfInteger)
+ GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
+ const TopoDS_Shape& theShape,
+ TopAbs_ShapeEnum theShapeType,
+ GEOMAlgo_State theState)
+{
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
+
+ // Check presence of triangulation, build if need
+ if (!CheckTriangulation(theShape)) {
+ SetErrorCode("Cannot build triangulation on the shape");
+ return aSeqOfIDs;
+ }
+
+ // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
+ // Compute tolerance
+ Standard_Real T, VertMax = -RealLast();
+ try {
+#if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
+ OCC_CATCH_SIGNALS;
+#endif
+ for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
+ TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
+ T = BRep_Tool::Tolerance(Vertex);
+ if (T > VertMax)
+ VertMax = T;
+ }
+ }
+ catch (Standard_Failure) {
+ Handle(Standard_Failure) aFail = Standard_Failure::Caught();
+ SetErrorCode(aFail->GetMessageString());
+ return aSeqOfIDs;
+ }
+ // END: Mantis issue 0020961
+
+ // Call algo
+ GEOMAlgo_FinderShapeOn1 aFinder;
+ //Standard_Real aTol = 0.0001; // default value
+ Standard_Real aTol = VertMax; // Mantis issue 0020961
+
+ aFinder.SetShape(theShape);
+ aFinder.SetTolerance(aTol);
+ aFinder.SetSurface(theSurface);
+ aFinder.SetShapeType(theShapeType);
+ aFinder.SetState(theState);
+
+ // Sets the minimal number of inner points for the faces that do not have own
+ // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
+ // Default value=3
+ aFinder.SetNbPntsMin(3);
+ // Sets the maximal number of inner points for edges or faces.
+ // It is usefull for the cases when this number is very big (e.g =2000) to improve
+ // the performance. If this value =0, all inner points will be taken into account.
+ // Default value=0
+ aFinder.SetNbPntsMax(100);
+
+ aFinder.Perform();
+
+ // Interprete results
+ Standard_Integer iErr = aFinder.ErrorStatus();
+ // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iErr) {
+ MESSAGE(" iErr : " << iErr);
+ TCollection_AsciiString aMsg (" iErr : ");
+ aMsg += TCollection_AsciiString(iErr);
+ SetErrorCode(aMsg);
+ return aSeqOfIDs;
+ }
+ Standard_Integer iWrn = aFinder.WarningStatus();
+ // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
+ if (iWrn) {
+ MESSAGE(" *** iWrn : " << iWrn);
+ }
+
+ const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
+
+ if (listSS.Extent() < 1) {
+ //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
+ SetErrorCode(NOT_FOUND_ANY); // NPAL18017
+ return aSeqOfIDs;
+ }
+
+ // Fill sequence of object IDs
+ aSeqOfIDs = new TColStd_HSequenceOfInteger;
+
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(theShape, anIndices);
+
+ TopTools_ListIteratorOfListOfShape itSub (listSS);
+ for (int index = 1; itSub.More(); itSub.Next(), ++index) {
+ int id = anIndices.FindIndex(itSub.Value());
+ aSeqOfIDs->Append(id);
+ }
+
+ return aSeqOfIDs;
+}
+
+//=======================================================================
+//function : getObjectsShapesOn
+/*!
+ * \brief Find shape objects and their entries by their ids
+ * \param theShapeIDs - incoming shape ids
+ * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
+ * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
+ getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
+ const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
+ TCollection_AsciiString & theShapeEntries)
+{
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+
+ if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
+ {
+ aSeq = new TColStd_HSequenceOfTransient;
+ Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
+ TCollection_AsciiString anEntry;
+ for ( int i = 1; i <= theShapeIDs->Length(); ++i )
+ {
+ anArray->SetValue(1, theShapeIDs->Value( i ));
+ Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
+ aSeq->Append( anObj );
+
+ TDF_Tool::Entry(anObj->GetEntry(), anEntry);
+ if ( i != 1 ) theShapeEntries += ",";
+ theShapeEntries += anEntry;
+ }
+ }
+ return aSeq;
+}
+
+//=======================================================================
+//function : getShapesOnSurface
+/*!
+ * \brief Find subshapes complying with given status about surface
+ * \param theSurface - the surface to check state of subshapes against
+ * \param theShape - the shape to explore
+ * \param theShapeType - type of subshape of theShape
+ * \param theState - required state
+ * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
+ * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
+ */
+//=======================================================================
+Handle(TColStd_HSequenceOfTransient)
+ GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
+ const Handle(GEOM_Object)& theShape,
+ TopAbs_ShapeEnum theShapeType,
+ GEOMAlgo_State theState,
+ TCollection_AsciiString & theShapeEntries)
+{
+ // Find subshapes ids
+ Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
+ getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
+ if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
+ return NULL;
+
+ return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnPlane
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAx1,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAx1.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAx1 = theAx1->GetValue();
+
+ if (aShape.IsNull() || anAx1.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( theShapeType ))
+ return NULL;
+
+ // Create plane
+ Handle(Geom_Surface) aPlane = makePlane( anAx1 );
+ if ( aPlane.IsNull() )
+ return NULL;
+
+ // Find objects
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->Length() == 0 )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetShapesOnPlane(" << theShape << ", "
+ << aShapeType << ", " << theAx1 << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnPlaneWithLocation
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAx1,
+ const Handle(GEOM_Object)& thePnt,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAx1 = theAx1->GetValue();
+ TopoDS_Shape anPnt = thePnt->GetValue();
+
+ if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( theShapeType ))
+ return NULL;
+
+ // Create plane
+ if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
+ TopoDS_Vertex V1, V2, V3;
+ TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
+ TopExp::Vertices(anEdge, V1, V2, Standard_True);
+
+ if (V1.IsNull() || V2.IsNull()) {
+ SetErrorCode("Bad edge given for the plane normal vector");
+ return NULL;
+ }
+ V3 = TopoDS::Vertex(anPnt);
+
+ if(V3.IsNull()) {
+ SetErrorCode("Bad vertex given for the plane location");
+ return NULL;
+ }
+ gp_Pnt aLoc = BRep_Tool::Pnt(V3);
+ gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
+
+ if (aVec.Magnitude() < Precision::Confusion()) {
+ SetErrorCode("Vector with null magnitude given");
+ return NULL;
+ }
+ Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
+
+ if ( aPlane.IsNull() )
+ return NULL;
+
+ // Find objects
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->Length() == 0 )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
+ << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnCylinder
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAxis,
+ const Standard_Real theRadius,
+ const GEOMAlgo_State theState)
+{
+ 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 ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Create a cylinder surface
+ Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
+ if ( aCylinder.IsNull() )
+ return NULL;
+
+ // Find objects
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->Length() == 0 )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
+ << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnCylinderWithLocation
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theAxis,
+ const Handle(GEOM_Object)& thePnt,
+ const Standard_Real theRadius,
+ const GEOMAlgo_State theState)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
+
+ TopoDS_Shape aShape = theShape->GetValue();
+ TopoDS_Shape anAxis = theAxis->GetValue();
+ TopoDS_Shape aPnt = thePnt->GetValue();
+
+ if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
+
+ if (aPnt.ShapeType() != TopAbs_VERTEX )
+ {
+ SetErrorCode("Bottom location point must be vertex");
+ return NULL;
+ }
+
+ TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
+ if ( !checkTypeShapesOn( aShapeType ))
+ return NULL;
+
+ // Create a cylinder surface
+ Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
+ if ( aCylinder.IsNull() )
+ return NULL;
+
+ // translate the surface
+ Handle(Geom_CylindricalSurface) aCylSurface =
+ Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
+ if ( aCylSurface.IsNull() )
+ {
+ SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
+ return NULL;
+ }
+ gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
+ gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
+ aCylinder->Translate( fromLoc, toLoc );
+
+ // Find objects
+ TCollection_AsciiString anAsciiList;
+ Handle(TColStd_HSequenceOfTransient) aSeq;
+ aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
+ if ( aSeq.IsNull() || aSeq->Length() == 0 )
+ return NULL;
+
+ // Make a Python command
+
+ Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
+ Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
+
+ GEOM::TPythonDump(aFunction)
+ << "[" << anAsciiList.ToCString()
+ << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
+ << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * GetShapesOnSphere
+ */
+//=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
+ (const Handle(GEOM_Object)& theShape,
+ const Standard_Integer theShapeType,
+ const Handle(GEOM_Object)& theCenter,
+ const Standard_Real theRadius,
+ const GEOMAlgo_State theState)
+{
+ 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;