1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File : GEOMImpl_IShapesOperations.cxx
24 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
27 #include <Standard_Stream.hxx>
29 #include "GEOMImpl_IShapesOperations.hxx"
31 #include "GEOMImpl_Types.hxx"
33 #include "GEOMImpl_VectorDriver.hxx"
34 #include "GEOMImpl_ShapeDriver.hxx"
35 #include "GEOMImpl_CopyDriver.hxx"
36 #include "GEOMImpl_GlueDriver.hxx"
38 #include "GEOMImpl_IVector.hxx"
39 #include "GEOMImpl_IShapes.hxx"
40 #include "GEOMImpl_IGlue.hxx"
42 #include "GEOMImpl_Block6Explorer.hxx"
44 #include "GEOM_Function.hxx"
45 #include "GEOM_ISubShape.hxx"
46 #include "GEOM_PythonDump.hxx"
48 #include "GEOMAlgo_FinderShapeOn1.hxx"
49 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
50 #include "GEOMAlgo_FinderShapeOn2.hxx"
51 #include "GEOMAlgo_ClsfBox.hxx"
52 #include "GEOMAlgo_ClsfSolid.hxx"
53 #include "GEOMAlgo_Gluer1.hxx"
54 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
55 #include "GEOMAlgo_CoupleOfShapes.hxx"
56 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
58 #include "utilities.h"
60 #include "Utils_ExceptHandlers.hxx"
62 #include <TFunction_DriverTable.hxx>
63 #include <TFunction_Driver.hxx>
64 #include <TFunction_Logbook.hxx>
65 #include <TDataStd_Integer.hxx>
66 #include <TDataStd_IntegerArray.hxx>
67 #include <TDataStd_ListIteratorOfListOfExtendedString.hxx>
68 #include <TDF_Tool.hxx>
70 #include <BRepExtrema_ExtCF.hxx>
71 #include <BRepExtrema_DistShapeShape.hxx>
73 #include <BRep_Tool.hxx>
74 #include <BRep_Builder.hxx>
75 #include <BRepTools.hxx>
76 #include <BRepGProp.hxx>
77 #include <BRepAdaptor_Curve.hxx>
78 #include <BRepAdaptor_Surface.hxx>
79 #include <BRepBndLib.hxx>
80 #include <BRepBuilderAPI_MakeFace.hxx>
81 #include <BRepMesh_IncrementalMesh.hxx>
86 #include <TopoDS_Shape.hxx>
87 #include <TopoDS_Solid.hxx>
88 #include <TopoDS_Face.hxx>
89 #include <TopoDS_Edge.hxx>
90 #include <TopoDS_Vertex.hxx>
91 #include <TopoDS_Compound.hxx>
92 #include <TopoDS_Iterator.hxx>
93 #include <TopExp_Explorer.hxx>
94 #include <TopLoc_Location.hxx>
95 #include <TopTools_MapOfShape.hxx>
96 #include <TopTools_MapOfOrientedShape.hxx>
97 #include <TopTools_Array1OfShape.hxx>
98 #include <TopTools_ListIteratorOfListOfShape.hxx>
99 #include <TopTools_IndexedMapOfShape.hxx>
101 #include <Geom_Surface.hxx>
102 #include <Geom_Plane.hxx>
103 #include <Geom_SphericalSurface.hxx>
104 #include <Geom_CylindricalSurface.hxx>
105 #include <GeomAdaptor_Surface.hxx>
107 #include <GeomLib_Tool.hxx>
108 #include <Geom2d_Curve.hxx>
110 #include <Bnd_Box.hxx>
111 #include <GProp_GProps.hxx>
112 #include <TColStd_Array1OfReal.hxx>
113 #include <TColStd_HArray1OfInteger.hxx>
114 #include <TColStd_ListIteratorOfListOfInteger.hxx>
115 #include <TColStd_ListOfInteger.hxx>
116 #include <gp_Cylinder.hxx>
117 #include <gp_Lin.hxx>
118 #include <gp_Pnt.hxx>
122 #include <Standard_NullObject.hxx>
123 #include <Standard_Failure.hxx>
124 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
126 // Includes added for GetInPlace algorithm improvement
128 #include <GEOMImpl_MeasureDriver.hxx>
129 #include <GEOMImpl_IMeasure.hxx>
130 #include <BRepBuilderAPI_MakeVertex.hxx>
132 #include <BRepClass_FaceClassifier.hxx>
133 #include <BRepClass3d_SolidClassifier.hxx>
134 #include <Precision.hxx>
136 //=============================================================================
140 //=============================================================================
141 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
142 : GEOM_IOperations(theEngine, theDocID)
144 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
147 //=============================================================================
151 //=============================================================================
152 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
154 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
157 //=============================================================================
161 //=============================================================================
162 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
163 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
167 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
169 //Add a new Edge object
170 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
172 //Add a new Vector function
173 Handle(GEOM_Function) aFunction =
174 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
176 //Check if the function is set correctly
177 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
179 GEOMImpl_IVector aPI (aFunction);
181 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
182 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
183 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
185 aPI.SetPoint1(aRef1);
186 aPI.SetPoint2(aRef2);
188 //Compute the Edge value
190 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
193 if (!GetSolver()->ComputeFunction(aFunction)) {
194 SetErrorCode("Vector driver failed");
198 catch (Standard_Failure) {
199 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
200 SetErrorCode(aFail->GetMessageString());
204 //Make a Python command
205 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
206 << thePnt1 << ", " << thePnt2 << ")";
212 //=============================================================================
214 * MakeEdgeOnCurveByLength
216 //=============================================================================
217 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeOnCurveByLength
218 (Handle(GEOM_Object) theRefCurve,
219 const Standard_Real theLength,
220 Handle(GEOM_Object) theStartPoint)
224 if (theRefCurve.IsNull()) return NULL;
226 //Add a new Edge object
227 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
229 //Add a new Vector function
230 Handle(GEOM_Function) aFunction =
231 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_CURVE_LENGTH);
233 //Check if the function is set correctly
234 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
236 GEOMImpl_IVector aPI (aFunction);
238 Handle(GEOM_Function) aRef1 = theRefCurve->GetLastFunction();
239 if (aRef1.IsNull()) return NULL;
240 aPI.SetPoint1(aRef1);
242 if (!theStartPoint.IsNull()) {
243 Handle(GEOM_Function) aRef2 = theStartPoint->GetLastFunction();
244 aPI.SetPoint2(aRef2);
247 aPI.SetParameter(theLength);
249 //Compute the Edge value
251 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
254 if (!GetSolver()->ComputeFunction(aFunction)) {
255 SetErrorCode("Vector driver failed");
259 catch (Standard_Failure) {
260 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
261 SetErrorCode(aFail->GetMessageString());
265 //Make a Python command
266 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeOnCurveByLength("
267 << theRefCurve << ", " << theLength << ", " << theStartPoint << ")";
273 //=============================================================================
277 //=============================================================================
278 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdgeWire
279 (Handle(GEOM_Object) theWire,
280 const Standard_Real theLinearTolerance,
281 const Standard_Real theAngularTolerance)
285 if (theWire.IsNull()) return NULL;
287 //Add a new Edge object
288 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
290 //Add a new Vector function
291 Handle(GEOM_Function) aFunction =
292 anEdge->AddFunction(GEOMImpl_ShapeDriver::GetID(), EDGE_WIRE);
294 //Check if the function is set correctly
295 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
297 GEOMImpl_IShapes aCI (aFunction);
299 Handle(GEOM_Function) aWire = theWire->GetLastFunction();
301 if (aWire.IsNull()) return NULL;
304 aCI.SetTolerance(theLinearTolerance);
305 aCI.SetAngularTolerance(theAngularTolerance);
307 //Compute the Edge value
309 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
312 if (!GetSolver()->ComputeFunction(aFunction)) {
313 SetErrorCode("Shape driver failed");
317 catch (Standard_Failure) {
318 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
319 SetErrorCode(aFail->GetMessageString());
323 const double DEF_LIN_TOL = Precision::Confusion();
324 const double DEF_ANG_TOL = Precision::Angular();
325 //Make a Python command
326 if ( theAngularTolerance == DEF_ANG_TOL ) {
327 if ( theLinearTolerance == DEF_LIN_TOL )
328 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
331 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
332 << theWire << ", " << theLinearTolerance << ")";
335 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdgeWire("
336 << theWire << ", " << theLinearTolerance << ", "
337 << theAngularTolerance << ")";
344 //=============================================================================
348 //=============================================================================
349 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
350 (std::list<Handle(GEOM_Object)> theShapes,
351 const Standard_Real theTolerance)
356 Handle(GEOM_Object) aWire = GetEngine()->AddObject(GetDocID(), GEOM_WIRE);
359 Handle(GEOM_Function) aFunction =
360 aWire->AddFunction(GEOMImpl_ShapeDriver::GetID(), WIRE_EDGES);
361 if (aFunction.IsNull()) return NULL;
363 //Check if the function is set correctly
364 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
366 GEOMImpl_IShapes aCI (aFunction);
367 aCI.SetTolerance(theTolerance);
369 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
372 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
373 for (; it != theShapes.end(); it++) {
374 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
375 if (aRefSh.IsNull()) {
376 SetErrorCode("NULL argument shape for the shape construction");
379 aShapesSeq->Append(aRefSh);
381 aCI.SetShapes(aShapesSeq);
385 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
388 if (!GetSolver()->ComputeFunction(aFunction)) {
389 SetErrorCode("Shape driver failed");
393 catch (Standard_Failure) {
394 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
395 SetErrorCode(aFail->GetMessageString());
399 //Make a Python command
400 GEOM::TPythonDump pd (aFunction);
401 pd << aWire << " = geompy.MakeWire([";
404 it = theShapes.begin();
405 if (it != theShapes.end()) {
407 while (it != theShapes.end()) {
408 pd << ", " << (*it++);
411 pd << "], " << theTolerance << ")";
417 //=============================================================================
421 //=============================================================================
422 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
423 const bool isPlanarWanted)
427 if (theWire.IsNull()) return NULL;
429 //Add a new Face object
430 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
432 //Add a new Shape function for creation of a face from a wire
433 Handle(GEOM_Function) aFunction =
434 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
435 if (aFunction.IsNull()) return NULL;
437 //Check if the function is set correctly
438 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
440 GEOMImpl_IShapes aCI (aFunction);
442 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
444 if (aRefWire.IsNull()) return NULL;
446 aCI.SetBase(aRefWire);
447 aCI.SetIsPlanar(isPlanarWanted);
449 //Compute the Face value
451 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
454 if (!GetSolver()->ComputeFunction(aFunction)) {
455 SetErrorCode("Shape driver failed to compute a face");
459 catch (Standard_Failure) {
460 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
461 SetErrorCode(aFail->GetMessageString());
465 //Make a Python command
466 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
467 << theWire << ", " << (int)isPlanarWanted << ")";
473 //=============================================================================
477 //=============================================================================
478 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
479 (std::list<Handle(GEOM_Object)> theShapes,
480 const bool isPlanarWanted)
485 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
488 Handle(GEOM_Function) aFunction =
489 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
490 if (aFunction.IsNull()) return NULL;
492 //Check if the function is set correctly
493 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
495 GEOMImpl_IShapes aCI (aFunction);
497 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
500 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
501 for (; it != theShapes.end(); it++) {
502 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
503 if (aRefSh.IsNull()) {
504 SetErrorCode("NULL argument shape for the face construction");
507 aShapesSeq->Append(aRefSh);
509 aCI.SetShapes(aShapesSeq);
511 aCI.SetIsPlanar(isPlanarWanted);
515 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
518 if (!GetSolver()->ComputeFunction(aFunction)) {
519 SetErrorCode("Shape driver failed");
523 catch (Standard_Failure) {
524 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
525 SetErrorCode(aFail->GetMessageString());
529 //Make a Python command
530 GEOM::TPythonDump pd (aFunction);
531 pd << aShape << " = geompy.MakeFaceWires([";
534 it = theShapes.begin();
535 if (it != theShapes.end()) {
537 while (it != theShapes.end()) {
538 pd << ", " << (*it++);
541 pd << "], " << (int)isPlanarWanted << ")";
547 //=============================================================================
551 //=============================================================================
552 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
553 (std::list<Handle(GEOM_Object)> theShapes)
555 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
558 //=============================================================================
562 //=============================================================================
563 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
564 (std::list<Handle(GEOM_Object)> theShapes)
566 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
569 //=============================================================================
573 //=============================================================================
574 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
575 (std::list<Handle(GEOM_Object)> theShapes)
577 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
580 //=============================================================================
584 //=============================================================================
585 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
586 (std::list<Handle(GEOM_Object)> theShapes,
587 const Standard_Integer theObjectType,
588 const Standard_Integer theFunctionType,
589 const TCollection_AsciiString& theMethodName)
594 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
597 Handle(GEOM_Function) aFunction =
598 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
599 if (aFunction.IsNull()) return NULL;
601 //Check if the function is set correctly
602 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
604 GEOMImpl_IShapes aCI (aFunction);
606 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
609 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
610 for (; it != theShapes.end(); it++) {
611 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
612 if (aRefSh.IsNull()) {
613 SetErrorCode("NULL argument shape for the shape construction");
616 aShapesSeq->Append(aRefSh);
618 aCI.SetShapes(aShapesSeq);
622 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
625 if (!GetSolver()->ComputeFunction(aFunction)) {
626 SetErrorCode("Shape driver failed");
630 catch (Standard_Failure) {
631 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
632 SetErrorCode(aFail->GetMessageString());
636 //Make a Python command
637 GEOM::TPythonDump pd (aFunction);
638 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
641 it = theShapes.begin();
642 if (it != theShapes.end()) {
644 while (it != theShapes.end()) {
645 pd << ", " << (*it++);
654 //=============================================================================
658 //=============================================================================
659 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
660 (Handle(GEOM_Object) theShape,
661 const Standard_Real theTolerance,
662 const Standard_Boolean doKeepNonSolids)
666 if (theShape.IsNull()) return NULL;
668 //Add a new Glued object
669 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
671 //Add a new Glue function
672 Handle(GEOM_Function) aFunction;
673 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
674 if (aFunction.IsNull()) return NULL;
676 //Check if the function is set correctly
677 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
679 GEOMImpl_IGlue aCI (aFunction);
681 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
682 if (aRefShape.IsNull()) return NULL;
684 aCI.SetBase(aRefShape);
685 aCI.SetTolerance(theTolerance);
686 aCI.SetKeepNonSolids(doKeepNonSolids);
688 //Compute the sub-shape value
689 Standard_Boolean isWarning = Standard_False;
691 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
694 if (!GetSolver()->ComputeFunction(aFunction)) {
695 SetErrorCode("Shape driver failed to glue faces");
699 catch (Standard_Failure) {
700 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
701 SetErrorCode(aFail->GetMessageString());
702 // to provide warning
703 if (!aFunction->GetValue().IsNull()) {
704 isWarning = Standard_True;
710 //Make a Python command
711 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
712 << theShape << ", " << theTolerance << ")";
714 // to provide warning
715 if (!isWarning) SetErrorCode(OK);
719 //=============================================================================
723 //=============================================================================
724 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
725 (Handle(GEOM_Object) theShape,
726 const Standard_Real theTolerance)
730 if (theShape.IsNull()) return NULL;
731 TopoDS_Shape aShape = theShape->GetValue();
732 if (aShape.IsNull()) return NULL;
734 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
736 Standard_Integer iErr;
738 GEOMAlgo_Gluer1 aGluer;
739 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
740 GEOMAlgo_CoupleOfShapes aCS;
741 GEOMAlgo_ListOfCoupleOfShapes aLCS;
743 //aGluer = new GEOMAlgo_Gluer1;
744 aGluer.SetShape(aShape);
745 aGluer.SetTolerance(theTolerance);
747 iErr = aGluer.ErrorStatus();
748 if (iErr) return NULL;
750 TopTools_ListOfShape listShape;
751 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
753 aItCS.Initialize(aLCSG);
754 for (; aItCS.More(); aItCS.Next()) {
755 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
756 listShape.Append(aCSG.Shape1());
759 TopTools_ListIteratorOfListOfShape itSub (listShape);
760 TCollection_AsciiString anAsciiList, anEntry;
761 TopTools_IndexedMapOfShape anIndices;
762 TopExp::MapShapes(aShape, anIndices);
763 Handle(TColStd_HArray1OfInteger) anArray;
764 Handle(GEOM_Object) anObj;
765 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
766 TopoDS_Shape aValue = itSub.Value();
767 anArray = new TColStd_HArray1OfInteger(1,1);
768 anArray->SetValue(1, anIndices.FindIndex(aValue));
769 anObj = GetEngine()->AddSubShape(theShape, anArray);
770 if (!anObj.IsNull()) {
773 // for python command
774 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
775 anAsciiList += anEntry;
780 //Make a Python command
781 if( anAsciiList.Length() > 0 ) {
782 anAsciiList.Trunc(anAsciiList.Length() - 1);
783 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
784 GEOM::TPythonDump pd (aFunction, /*append=*/true);
785 pd << "[" << anAsciiList.ToCString();
786 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
794 //=============================================================================
796 * MakeGlueFacesByList
798 //=============================================================================
799 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
800 (Handle(GEOM_Object) theShape,
801 const Standard_Real theTolerance,
802 std::list<Handle(GEOM_Object)> theFaces,
803 const Standard_Boolean doKeepNonSolids)
807 if (theShape.IsNull()) return NULL;
809 //Add a new Glued object
810 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
812 //Add a new Glue function
813 Handle(GEOM_Function) aFunction;
814 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
815 if (aFunction.IsNull()) return NULL;
817 //Check if the function is set correctly
818 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
820 GEOMImpl_IGlue aCI (aFunction);
822 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
823 if (aRefShape.IsNull()) return NULL;
825 aCI.SetBase(aRefShape);
826 aCI.SetTolerance(theTolerance);
827 aCI.SetKeepNonSolids(doKeepNonSolids);
829 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
830 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
831 for (; it != theFaces.end(); it++) {
832 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
833 if (aRefSh.IsNull()) {
834 SetErrorCode("NULL argument shape for the shape construction");
837 aFaces->Append(aRefSh);
839 aCI.SetFaces(aFaces);
841 //Compute the sub-shape value
842 Standard_Boolean isWarning = Standard_False;
844 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
847 if (!GetSolver()->ComputeFunction(aFunction)) {
848 SetErrorCode("Shape driver failed to glue faces");
852 catch (Standard_Failure) {
853 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
854 SetErrorCode(aFail->GetMessageString());
855 // to provide warning
856 if (!aFunction->GetValue().IsNull()) {
857 isWarning = Standard_True;
863 //Make a Python command
865 GEOM::TPythonDump pd(aFunction);
866 pd << aGlued << " = geompy.MakeGlueFacesByList("
867 << theShape << ", " << theTolerance << ", [";
869 it = theFaces.begin();
870 if (it != theFaces.end()) {
872 while (it != theFaces.end()) {
873 pd << ", " << (*it++);
878 // to provide warning
879 if (!isWarning) SetErrorCode(OK);
883 //=============================================================================
885 * GetExistingSubObjects
887 //=============================================================================
888 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetExistingSubObjects
889 (Handle(GEOM_Object) theShape,
890 const Standard_Boolean theGroupsOnly)
894 if (theShape.IsNull()) return NULL;
896 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
897 if (aMainShape.IsNull()) return NULL;
899 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
900 SetErrorCode(NOT_FOUND_ANY);
902 if (!aMainShape->HasSubShapeReferences()) return aSeq;
903 const TDataStd_ListOfExtendedString& aListEntries = aMainShape->GetSubShapeReferences();
904 if (aListEntries.IsEmpty()) return aSeq;
908 TCollection_AsciiString anAsciiList;
910 TDataStd_ListIteratorOfListOfExtendedString anIt (aListEntries);
911 for (; anIt.More(); anIt.Next()) {
912 TCollection_ExtendedString anEntry = anIt.Value();
913 Standard_Integer aStrLen = anEntry.LengthOfCString();
914 char* anEntryStr = new char[aStrLen];
915 anEntry.ToUTF8CString(anEntryStr);
916 Handle(GEOM_Object) anObj = GetEngine()->GetObject(GetDocID(), anEntryStr, false);
917 if (!anObj.IsNull()) {
918 if (!theGroupsOnly || anObj->GetType() == GEOM_GROUP) {
921 // for python command
922 anAsciiList += anEntryStr;
926 delete [] anEntryStr;
929 if (aSeq->Length() == 0) {
930 SetErrorCode(NOT_FOUND_ANY);
934 //Make a Python command
935 anAsciiList.Trunc(anAsciiList.Length() - 1);
937 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
938 pd << "[" << anAsciiList.ToCString();
939 pd << "] = geompy.GetExistingSubObjects(";
940 pd << theShape << ", " << (int)theGroupsOnly << ")";
947 //=============================================================================
951 //=============================================================================
952 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
953 (Handle(GEOM_Object) theShape,
954 const Standard_Integer theShapeType,
955 const Standard_Boolean isSorted,
956 const ExplodeType theExplodeType)
960 if (theShape.IsNull()) return NULL;
961 TopoDS_Shape aShape = theShape->GetValue();
962 if (aShape.IsNull()) return NULL;
964 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
966 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
967 Handle(GEOM_Object) anObj;
968 TopTools_MapOfShape mapShape;
969 TopTools_ListOfShape listShape;
971 if (aShape.ShapeType() == TopAbs_COMPOUND &&
972 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
973 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
974 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
976 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
977 for (; It.More(); It.Next()) {
978 if (mapShape.Add(It.Value())) {
979 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
980 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
981 listShape.Append(It.Value());
986 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
988 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
989 for (; exp.More(); exp.Next())
990 if (mapShape.Add(exp.Current()))
991 listShape.Append(exp.Current());
994 if (listShape.IsEmpty()) {
995 //SetErrorCode("The given shape has no sub-shapes of the requested type");
996 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1001 bool isOldSorting = false;
1002 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1003 isOldSorting = true;
1004 SortShapes(listShape, isOldSorting);
1007 TopTools_IndexedMapOfShape anIndices;
1008 TopExp::MapShapes(aShape, anIndices);
1009 Handle(TColStd_HArray1OfInteger) anArray;
1011 TopTools_ListIteratorOfListOfShape itSub (listShape);
1012 TCollection_AsciiString anAsciiList, anEntry;
1013 for (int index = 1; itSub.More(); itSub.Next(), ++index)
1015 TopoDS_Shape aValue = itSub.Value();
1016 anArray = new TColStd_HArray1OfInteger(1,1);
1017 anArray->SetValue(1, anIndices.FindIndex(aValue));
1019 //anObj = GetEngine()->AddSubShape(theShape, anArray);
1021 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
1022 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
1023 if (aFunction.IsNull()) return aSeq;
1025 GEOM_ISubShape aSSI (aFunction);
1026 aSSI.SetMainShape(aMainShape);
1027 aSSI.SetIndices(anArray);
1029 // Set function value directly, as we know it.
1030 // Usage of Solver here would lead to significant loss of time,
1031 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
1032 // on the main shape for each being calculated sub-shape separately.
1033 aFunction->SetValue(aValue);
1036 if (!anObj.IsNull()) {
1037 aSeq->Append(anObj);
1039 // for python command
1040 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1041 anAsciiList += anEntry;
1046 //Make a Python command
1047 anAsciiList.Trunc(anAsciiList.Length() - 1);
1049 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1050 pd << "[" << anAsciiList.ToCString() << "] = geompy.";
1051 switch (theExplodeType) {
1052 case EXPLODE_NEW_EXCLUDE_MAIN:
1053 pd << "ExtractShapes(" << theShape << ", "
1054 << TopAbs_ShapeEnum(theShapeType) << ", " << (isSorted ? "True" : "False") << ")";
1056 case EXPLODE_NEW_INCLUDE_MAIN:
1057 pd << "SubShapeAll" << (isSorted ? "SortedCentres(" : "(")
1058 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1060 case EXPLODE_OLD_INCLUDE_MAIN:
1061 pd << "SubShapeAll" << (isSorted ? "Sorted(" : "(")
1062 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1071 //=============================================================================
1075 //=============================================================================
1076 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
1077 (Handle(GEOM_Object) theShape,
1078 const Standard_Integer theShapeType,
1079 const Standard_Boolean isSorted,
1080 const ExplodeType theExplodeType)
1084 if (theShape.IsNull()) return NULL;
1085 TopoDS_Shape aShape = theShape->GetValue();
1086 if (aShape.IsNull()) return NULL;
1088 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1089 TopTools_MapOfShape mapShape;
1090 TopTools_ListOfShape listShape;
1092 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1093 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1094 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1095 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND))
1097 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1098 for (; It.More(); It.Next()) {
1099 if (mapShape.Add(It.Value())) {
1100 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1101 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1102 listShape.Append(It.Value());
1107 else if (theExplodeType != EXPLODE_NEW_EXCLUDE_MAIN || aShape.ShapeType() != theShapeType) // issue 0021079
1109 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1110 for (; exp.More(); exp.Next())
1111 if (mapShape.Add(exp.Current()))
1112 listShape.Append(exp.Current());
1115 if (listShape.IsEmpty()) {
1116 //SetErrorCode("The given shape has no sub-shapes of the requested type");
1117 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1122 bool isOldSorting = false;
1123 if (theExplodeType == EXPLODE_OLD_INCLUDE_MAIN)
1124 isOldSorting = true;
1125 SortShapes(listShape, isOldSorting);
1128 TopTools_IndexedMapOfShape anIndices;
1129 TopExp::MapShapes(aShape, anIndices);
1130 Handle(TColStd_HArray1OfInteger) anArray;
1132 TopTools_ListIteratorOfListOfShape itSub (listShape);
1133 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1134 TopoDS_Shape aValue = itSub.Value();
1135 aSeq->Append(anIndices.FindIndex(aValue));
1138 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1140 //Make a Python command
1141 GEOM::TPythonDump pd (aFunction, /*append=*/true);
1142 pd << "listSubShapeIDs = geompy.SubShapeAll";
1143 switch (theExplodeType) {
1144 case EXPLODE_NEW_EXCLUDE_MAIN:
1146 case EXPLODE_NEW_INCLUDE_MAIN:
1147 pd << (isSorted ? "SortedCentresIDs(" : "IDs(")
1148 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1150 case EXPLODE_OLD_INCLUDE_MAIN:
1151 pd << (isSorted ? "SortedIDs(" : "IDs(")
1152 << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1161 //=============================================================================
1165 //=============================================================================
1166 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
1167 (Handle(GEOM_Object) theMainShape,
1168 const Standard_Integer theID)
1172 if (theMainShape.IsNull()) return NULL;
1174 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1175 anArray->SetValue(1, theID);
1176 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
1177 if (anObj.IsNull()) {
1178 SetErrorCode("Can not get a sub-shape with the given ID");
1182 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1184 //Make a Python command
1185 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
1186 << theMainShape << ", [" << theID << "])";
1192 //=============================================================================
1196 //=============================================================================
1197 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
1198 Handle(GEOM_Object) theSubShape)
1202 TopoDS_Shape aMainShape = theMainShape->GetValue();
1203 TopoDS_Shape aSubShape = theSubShape->GetValue();
1205 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
1207 TopTools_IndexedMapOfShape anIndices;
1208 TopExp::MapShapes(aMainShape, anIndices);
1209 if (anIndices.Contains(aSubShape)) {
1211 return anIndices.FindIndex(aSubShape);
1217 //=============================================================================
1221 //=============================================================================
1222 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
1223 Handle(GEOM_Object) theSubShape)
1227 TopoDS_Shape aMainShape = theMainShape->GetValue();
1228 TopoDS_Shape aSubShape = theSubShape->GetValue();
1230 if (aMainShape.IsNull() || aSubShape.IsNull()) {
1231 SetErrorCode("Null argument shape given");
1236 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
1238 TopTools_ListOfShape CL;
1239 CL.Append(aMainShape);
1240 TopTools_ListIteratorOfListOfShape itC;
1241 for (itC.Initialize(CL); itC.More(); itC.Next()) {
1242 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
1243 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
1244 if (it.Value().IsSame(aSubShape))
1248 CL.Append(it.Value());
1253 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1254 TopTools_MapOfShape M;
1255 for (; anExp.More(); anExp.Next()) {
1256 if (M.Add(anExp.Current())) {
1257 if (anExp.Current().IsSame(aSubShape))
1264 SetErrorCode("The sub-shape does not belong to the main shape");
1268 //=============================================================================
1270 * GetShapeTypeString
1272 //=============================================================================
1273 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1277 TCollection_AsciiString aTypeName ("Null Shape");
1279 TopoDS_Shape aShape = theShape->GetValue();
1280 if (aShape.IsNull())
1283 switch (aShape.ShapeType() )
1285 case TopAbs_COMPOUND:
1286 aTypeName = "Compound";
1288 case TopAbs_COMPSOLID:
1289 aTypeName = "Compound Solid";
1292 aTypeName = "Solid";
1295 aTypeName = "Shell";
1299 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1300 if (surf.GetType() == GeomAbs_Plane)
1301 aTypeName = "Plane";
1302 else if (surf.GetType() == GeomAbs_Cylinder)
1303 aTypeName = "Cylindrical Face";
1304 else if (surf.GetType() == GeomAbs_Sphere)
1305 aTypeName = "Spherical Face";
1306 else if (surf.GetType() == GeomAbs_Torus)
1307 aTypeName = "Toroidal Face";
1308 else if (surf.GetType() == GeomAbs_Cone)
1309 aTypeName = "Conical Face";
1311 aTypeName = "GEOM::FACE";
1319 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1320 if (curv.GetType() == GeomAbs_Line) {
1321 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1322 (Abs(curv.LastParameter()) >= 1E6))
1326 } else if (curv.GetType() == GeomAbs_Circle) {
1327 if (curv.IsClosed())
1328 aTypeName = "Circle";
1337 aTypeName = "Vertex";
1340 aTypeName = "Shape";
1343 aTypeName = "Shape of unknown type";
1349 //=============================================================================
1353 //=============================================================================
1354 Standard_Integer GEOMImpl_IShapesOperations::NumberOfSubShapes
1355 (Handle(GEOM_Object) theShape,
1356 const Standard_Integer theShapeType)
1359 Standard_Integer nbShapes = 0;
1361 if (theShape.IsNull()) return -1;
1362 TopoDS_Shape aShape = theShape->GetValue();
1363 if (aShape.IsNull()) return -1;
1366 TopTools_MapOfShape mapShape;
1368 if (aShape.ShapeType() == TopAbs_COMPOUND &&
1369 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1370 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
1371 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
1372 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
1373 for (; It.More(); It.Next()) {
1374 if (mapShape.Add(It.Value())) {
1375 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
1376 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
1382 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
1383 for (; exp.More(); exp.Next())
1384 if (mapShape.Add(exp.Current()))
1390 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1393 int iType, nbTypes [TopAbs_SHAPE];
1394 for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1396 nbTypes[aShape.ShapeType()]++;
1398 TopTools_MapOfShape aMapOfShape;
1399 aMapOfShape.Add(aShape);
1400 TopTools_ListOfShape aListOfShape;
1401 aListOfShape.Append(aShape);
1403 TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1404 for (; itL.More(); itL.Next()) {
1405 TopoDS_Iterator it (itL.Value());
1406 for (; it.More(); it.Next()) {
1407 TopoDS_Shape s = it.Value();
1408 if (aMapOfShape.Add(s)) {
1409 aListOfShape.Append(s);
1410 nbTypes[s.ShapeType()]++;
1415 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE)
1416 nbShapes = aMapOfShape.Extent();
1418 nbShapes = nbTypes[theShapeType];
1420 catch (Standard_Failure) {
1421 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1422 SetErrorCode(aFail->GetMessageString());
1430 //=============================================================================
1434 //=============================================================================
1435 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1439 if (theShape.IsNull()) return NULL;
1441 //Add a new reversed object
1442 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1444 //Add a new Revese function
1445 Handle(GEOM_Function) aFunction;
1446 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1447 if (aFunction.IsNull()) return NULL;
1449 //Check if the function is set correctly
1450 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1452 GEOMImpl_IShapes aSI (aFunction);
1454 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1455 if (aRefShape.IsNull()) return NULL;
1457 aSI.SetBase(aRefShape);
1459 //Compute the sub-shape value
1461 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1464 if (!GetSolver()->ComputeFunction(aFunction)) {
1465 SetErrorCode("Shape driver failed to reverse shape");
1469 catch (Standard_Failure) {
1470 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1471 SetErrorCode(aFail->GetMessageString());
1475 //Make a Python command
1476 GEOM::TPythonDump(aFunction) << aReversed
1477 << " = geompy.ChangeOrientation(" << theShape << ")";
1483 //=============================================================================
1487 //=============================================================================
1488 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1489 (Handle(GEOM_Object) theShape)
1493 if (theShape.IsNull()) return NULL;
1494 TopoDS_Shape aShape = theShape->GetValue();
1495 if (aShape.IsNull()) return NULL;
1497 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1499 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1500 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1501 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1503 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1506 SetErrorCode("The given shape has no faces");
1510 TopTools_IndexedMapOfShape anIndices;
1511 TopExp::MapShapes(aShape, anIndices);
1513 Standard_Integer id;
1514 for (; ind <= nbFaces; ind++) {
1515 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1516 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1521 //The explode doesn't change object so no new function is required.
1522 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1524 //Make a Python command
1525 GEOM::TPythonDump(aFunction, /*append=*/true)
1526 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1532 //=======================================================================
1533 //function : GetSharedShapes
1535 //=======================================================================
1536 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1537 (Handle(GEOM_Object) theShape1,
1538 Handle(GEOM_Object) theShape2,
1539 const Standard_Integer theShapeType)
1543 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1545 TopoDS_Shape aShape1 = theShape1->GetValue();
1546 TopoDS_Shape aShape2 = theShape2->GetValue();
1548 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1550 TopTools_IndexedMapOfShape anIndices;
1551 TopExp::MapShapes(aShape1, anIndices);
1552 Handle(TColStd_HArray1OfInteger) anArray;
1554 TopTools_IndexedMapOfShape mapShape1;
1555 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1557 Handle(GEOM_Object) anObj;
1558 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1559 TCollection_AsciiString anAsciiList, anEntry;
1561 TopTools_MapOfShape mapShape2;
1562 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1563 for (; exp.More(); exp.Next()) {
1564 TopoDS_Shape aSS = exp.Current();
1565 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1566 anArray = new TColStd_HArray1OfInteger(1,1);
1567 anArray->SetValue(1, anIndices.FindIndex(aSS));
1568 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1569 aSeq->Append(anObj);
1571 // for python command
1572 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1573 anAsciiList += anEntry;
1578 if (aSeq->IsEmpty()) {
1579 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1583 //Make a Python command
1584 anAsciiList.Trunc(anAsciiList.Length() - 1);
1586 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1588 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1589 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1590 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1596 //=======================================================================
1597 //function : GetSharedShapes
1599 //=======================================================================
1600 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1601 (std::list<Handle(GEOM_Object)> theShapes,
1602 const Standard_Integer theShapeType)
1606 int aLen = theShapes.size();
1607 if (aLen < 1) return NULL;
1610 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
1612 Handle(GEOM_Object) aMainObj = (*it++);
1613 Handle(GEOM_Function) aMainShape = aMainObj->GetLastFunction();
1614 if (aMainShape.IsNull()) {
1615 SetErrorCode("NULL shape for GetSharedShapes");
1619 TopoDS_Shape aShape1 = aMainShape->GetValue();
1620 if (aShape1.IsNull()) return NULL;
1622 TopTools_IndexedMapOfShape anIndices;
1623 TopExp::MapShapes(aShape1, anIndices);
1625 TopTools_IndexedMapOfShape mapSelected;
1626 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapSelected);
1628 // Find shared shapes
1630 TopoDS_Compound aCurrSelection;
1632 for (; it != theShapes.end(); it++, ind++) {
1633 Handle(GEOM_Function) aRefShape = (*it)->GetLastFunction();
1634 if (aRefShape.IsNull()) {
1635 SetErrorCode("NULL shape for GetSharedShapes");
1639 TopoDS_Compound aCompound;
1640 B.MakeCompound(aCompound);
1642 TopoDS_Shape aShape2 = aRefShape->GetValue();
1643 if (aShape2.IsNull()) return NULL;
1645 TopTools_MapOfShape mapShape2;
1646 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1647 for (; exp.More(); exp.Next()) {
1648 TopoDS_Shape aSS = exp.Current();
1649 if (mapShape2.Add(aSS) && mapSelected.Contains(aSS)) {
1650 B.Add(aCompound, aSS);
1654 mapSelected.Clear();
1655 TopExp::MapShapes(aCompound, TopAbs_ShapeEnum(theShapeType), mapSelected);
1656 aCurrSelection = aCompound;
1659 // Create GEOM_Object for each found shared shape (collected in aCurrSelection)
1660 Handle(GEOM_Object) anObj;
1661 Handle(TColStd_HArray1OfInteger) anArray;
1662 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1663 TCollection_AsciiString anAsciiList, anEntry;
1665 TopoDS_Iterator itSel (aCurrSelection, Standard_True, Standard_True);
1666 for (; itSel.More(); itSel.Next()) {
1667 anArray = new TColStd_HArray1OfInteger(1,1);
1668 anArray->SetValue(1, anIndices.FindIndex(itSel.Value()));
1669 anObj = GetEngine()->AddSubShape(aMainObj, anArray);
1670 aSeq->Append(anObj);
1672 // for python command
1673 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1674 anAsciiList += anEntry;
1678 if (aSeq->IsEmpty()) {
1679 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1683 // Make a Python command
1684 anAsciiList.Trunc(anAsciiList.Length() - 1);
1686 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
1687 pd << "[" << anAsciiList.ToCString()
1688 << "] = geompy.GetSharedShapesMulti([";
1690 it = theShapes.begin();
1692 while (it != theShapes.end()) {
1693 pd << ", " << (*it++);
1696 pd << "], " << TopAbs_ShapeEnum(theShapeType) << ")";
1702 //=============================================================================
1706 //=============================================================================
1707 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1708 const GEOMAlgo_State theState)
1711 case GEOMAlgo_ST_IN:
1712 theDump << "geompy.GEOM.ST_IN";
1714 case GEOMAlgo_ST_OUT:
1715 theDump << "geompy.GEOM.ST_OUT";
1717 case GEOMAlgo_ST_ON:
1718 theDump << "geompy.GEOM.ST_ON";
1720 case GEOMAlgo_ST_ONIN:
1721 theDump << "geompy.GEOM.ST_ONIN";
1723 case GEOMAlgo_ST_ONOUT:
1724 theDump << "geompy.GEOM.ST_ONOUT";
1727 theDump << "geompy.GEOM.ST_UNKNOWN";
1733 //=======================================================================
1734 //function : checkTypeShapesOn
1736 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1737 * \param theShapeType - the shape type to check
1738 * \retval bool - result of the check
1740 //=======================================================================
1741 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1743 if (theShapeType != TopAbs_VERTEX &&
1744 theShapeType != TopAbs_EDGE &&
1745 theShapeType != TopAbs_FACE &&
1746 theShapeType != TopAbs_SOLID) {
1747 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1753 //=======================================================================
1754 //function : makePlane
1756 * \brief Creates Geom_Plane
1757 * \param theAx1 - shape object defining plane parameters
1758 * \retval Handle(Geom_Surface) - resulting surface
1760 //=======================================================================
1761 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1763 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1764 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1765 TopoDS_Vertex V1, V2;
1766 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1767 if (V1.IsNull() || V2.IsNull()) {
1768 SetErrorCode("Bad edge given for the plane normal vector");
1771 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1772 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1773 if (aVec.Magnitude() < Precision::Confusion()) {
1774 SetErrorCode("Vector with null magnitude given");
1777 return new Geom_Plane(aLoc, aVec);
1780 //=======================================================================
1781 //function : makeCylinder
1783 * \brief Creates Geom_CylindricalSurface
1784 * \param theAx1 - edge defining cylinder axis
1785 * \param theRadius - cylinder radius
1786 * \retval Handle(Geom_Surface) - resulting surface
1788 //=======================================================================
1789 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1790 const Standard_Real theRadius)
1792 //Axis of the cylinder
1793 if (anAxis.ShapeType() != TopAbs_EDGE) {
1794 SetErrorCode("Not an edge given for the axis");
1797 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1798 TopoDS_Vertex V1, V2;
1799 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1800 if (V1.IsNull() || V2.IsNull()) {
1801 SetErrorCode("Bad edge given for the axis");
1804 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1805 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1806 if (aVec.Magnitude() < Precision::Confusion()) {
1807 SetErrorCode("Vector with null magnitude given");
1811 gp_Ax3 anAx3 (aLoc, aVec);
1812 return new Geom_CylindricalSurface(anAx3, theRadius);
1815 //=======================================================================
1816 //function : getShapesOnBoxIDs
1818 * \brief Find IDs of subshapes complying with given status about surface
1819 * \param theBox - the box to check state of subshapes against
1820 * \param theShape - the shape to explore
1821 * \param theShapeType - type of subshape of theShape
1822 * \param theState - required state
1823 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1825 //=======================================================================
1826 Handle(TColStd_HSequenceOfInteger)
1827 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1828 const Handle(GEOM_Object)& theShape,
1829 const Standard_Integer theShapeType,
1830 GEOMAlgo_State theState)
1832 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1834 TopoDS_Shape aBox = theBox->GetValue();
1835 TopoDS_Shape aShape = theShape->GetValue();
1837 // Check presence of triangulation, build if need
1838 if (!CheckTriangulation(aShape)) {
1839 SetErrorCode("Cannot build triangulation on the shape");
1844 GEOMAlgo_FinderShapeOn2 aFinder;
1845 Standard_Real aTol = 0.0001; // default value
1847 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1848 aClsfBox->SetBox(aBox);
1850 aFinder.SetShape(aShape);
1851 aFinder.SetTolerance(aTol);
1852 aFinder.SetClsf(aClsfBox);
1853 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1854 aFinder.SetState(theState);
1857 // Interprete results
1858 Standard_Integer iErr = aFinder.ErrorStatus();
1859 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1861 MESSAGE(" iErr : " << iErr);
1862 TCollection_AsciiString aMsg (" iErr : ");
1863 aMsg += TCollection_AsciiString(iErr);
1867 Standard_Integer iWrn = aFinder.WarningStatus();
1868 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1870 MESSAGE(" *** iWrn : " << iWrn);
1873 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1875 if (listSS.Extent() < 1) {
1876 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1877 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1881 // Fill sequence of object IDs
1882 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1884 TopTools_IndexedMapOfShape anIndices;
1885 TopExp::MapShapes(aShape, anIndices);
1887 TopTools_ListIteratorOfListOfShape itSub (listSS);
1888 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1889 int id = anIndices.FindIndex(itSub.Value());
1890 aSeqOfIDs->Append(id);
1896 //=======================================================================
1897 //function : GetShapesOnBoxIDs
1899 * \brief Find subshapes complying with given status about surface
1900 * \param theBox - the box to check state of subshapes against
1901 * \param theShape - the shape to explore
1902 * \param theShapeType - type of subshape of theShape
1903 * \param theState - required state
1904 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1906 //=======================================================================
1907 Handle(TColStd_HSequenceOfInteger)
1908 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1909 const Handle(GEOM_Object)& theShape,
1910 const Standard_Integer theShapeType,
1911 GEOMAlgo_State theState)
1913 // Find subshapes ids
1914 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1915 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1916 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1919 // The GetShapesOnBox() doesn't change object so no new function is required.
1920 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1922 // Make a Python command
1923 GEOM::TPythonDump(aFunction)
1924 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1927 << TopAbs_ShapeEnum(theShapeType) << ", "
1934 //=======================================================================
1935 //function : GetShapesOnBox
1937 * \brief Find subshapes complying with given status about surface
1938 * \param theBox - the box to check state of subshapes against
1939 * \param theShape - the shape to explore
1940 * \param theShapeType - type of subshape of theShape
1941 * \param theState - required state
1942 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1944 //=======================================================================
1945 Handle(TColStd_HSequenceOfTransient)
1946 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1947 const Handle(GEOM_Object)& theShape,
1948 const Standard_Integer theShapeType,
1949 GEOMAlgo_State theState)
1951 // Find subshapes ids
1952 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1953 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1954 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1957 // Find objects by indices
1958 TCollection_AsciiString anAsciiList;
1959 Handle(TColStd_HSequenceOfTransient) aSeq;
1960 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1961 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1964 // Make a Python command
1966 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1967 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1969 GEOM::TPythonDump(aFunction)
1970 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1973 << TopAbs_ShapeEnum(theShapeType) << ", "
1980 //=======================================================================
1981 //function : getShapesOnShapeIDs
1983 * \brief Find IDs of subshapes complying with given status about surface
1984 * \param theCheckShape - the shape to check state of subshapes against
1985 * \param theShape - the shape to explore
1986 * \param theShapeType - type of subshape of theShape
1987 * \param theState - required state
1988 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1990 //=======================================================================
1991 Handle(TColStd_HSequenceOfInteger)
1992 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1993 (const Handle(GEOM_Object)& theCheckShape,
1994 const Handle(GEOM_Object)& theShape,
1995 const Standard_Integer theShapeType,
1996 GEOMAlgo_State theState)
1998 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2000 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
2001 TopoDS_Shape aShape = theShape->GetValue();
2002 TopTools_ListOfShape res;
2004 // Check presence of triangulation, build if need
2005 if (!CheckTriangulation(aShape)) {
2006 SetErrorCode("Cannot build triangulation on the shape");
2011 GEOMAlgo_FinderShapeOn2 aFinder;
2012 Standard_Real aTol = 0.0001; // default value
2014 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
2015 aClsfSolid->SetShape(aCheckShape);
2017 aFinder.SetShape(aShape);
2018 aFinder.SetTolerance(aTol);
2019 aFinder.SetClsf(aClsfSolid);
2020 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
2021 aFinder.SetState(theState);
2024 // Interprete results
2025 Standard_Integer iErr = aFinder.ErrorStatus();
2026 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2029 SetErrorCode("theCheckShape must be a solid");
2032 MESSAGE(" iErr : " << iErr);
2033 TCollection_AsciiString aMsg (" iErr : ");
2034 aMsg += TCollection_AsciiString(iErr);
2039 Standard_Integer iWrn = aFinder.WarningStatus();
2040 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2042 MESSAGE(" *** iWrn : " << iWrn);
2045 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2047 if (listSS.Extent() < 1) {
2048 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2049 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2052 // Fill sequence of object IDs
2053 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2055 TopTools_IndexedMapOfShape anIndices;
2056 TopExp::MapShapes(aShape, anIndices);
2058 TopTools_ListIteratorOfListOfShape itSub (listSS);
2059 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2060 int id = anIndices.FindIndex(itSub.Value());
2061 aSeqOfIDs->Append(id);
2067 //=======================================================================
2068 //function : GetShapesOnShapeIDs
2070 * \brief Find subshapes complying with given status about surface
2071 * \param theCheckShape - the shape to check state of subshapes against
2072 * \param theShape - the shape to explore
2073 * \param theShapeType - type of subshape of theShape
2074 * \param theState - required state
2075 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2077 //=======================================================================
2078 Handle(TColStd_HSequenceOfInteger)
2079 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
2080 (const Handle(GEOM_Object)& theCheckShape,
2081 const Handle(GEOM_Object)& theShape,
2082 const Standard_Integer theShapeType,
2083 GEOMAlgo_State theState)
2085 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2086 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2088 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2091 // The GetShapesOnShape() doesn't change object so no new function is required.
2092 Handle(GEOM_Function) aFunction =
2093 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
2095 // Make a Python command
2096 GEOM::TPythonDump(aFunction)
2097 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
2098 << theCheckShape << ", "
2100 << TopAbs_ShapeEnum(theShapeType) << ", "
2107 //=======================================================================
2108 //function : GetShapesOnShape
2110 * \brief Find subshapes complying with given status about surface
2111 * \param theCheckShape - the shape to check state of subshapes against
2112 * \param theShape - the shape to explore
2113 * \param theShapeType - type of subshape of theShape
2114 * \param theState - required state
2115 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
2117 //=======================================================================
2118 Handle(TColStd_HSequenceOfTransient)
2119 GEOMImpl_IShapesOperations::GetShapesOnShape
2120 (const Handle(GEOM_Object)& theCheckShape,
2121 const Handle(GEOM_Object)& theShape,
2122 const Standard_Integer theShapeType,
2123 GEOMAlgo_State theState)
2125 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2126 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2127 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2130 // Find objects by indices
2131 TCollection_AsciiString anAsciiList;
2132 Handle(TColStd_HSequenceOfTransient) aSeq;
2133 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2135 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2138 // Make a Python command
2140 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2141 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2143 GEOM::TPythonDump(aFunction)
2144 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
2145 << theCheckShape << ", "
2147 << TopAbs_ShapeEnum(theShapeType) << ", "
2154 //=======================================================================
2155 //function : GetShapesOnShapeAsCompound
2156 //=======================================================================
2157 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
2158 (const Handle(GEOM_Object)& theCheckShape,
2159 const Handle(GEOM_Object)& theShape,
2160 const Standard_Integer theShapeType,
2161 GEOMAlgo_State theState)
2163 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2164 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
2166 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2169 // Find objects by indices
2170 TCollection_AsciiString anAsciiList;
2171 Handle(TColStd_HSequenceOfTransient) aSeq;
2172 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2174 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2177 TopoDS_Compound aCompound;
2179 B.MakeCompound(aCompound);
2181 for(; i<=aSeq->Length(); i++) {
2182 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
2183 TopoDS_Shape aShape_i = anObj->GetValue();
2184 B.Add(aCompound,aShape_i);
2187 //Add a new result object
2188 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
2189 Handle(GEOM_Function) aFunction =
2190 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
2191 aFunction->SetValue(aCompound);
2193 GEOM::TPythonDump(aFunction)
2194 << aRes << " = geompy.GetShapesOnShapeAsCompound("
2195 << theCheckShape << ", "
2197 << TopAbs_ShapeEnum(theShapeType) << ", "
2205 //=======================================================================
2206 //function : getShapesOnSurfaceIDs
2208 * \brief Find IDs of subshapes complying with given status about surface
2209 * \param theSurface - the surface to check state of subshapes against
2210 * \param theShape - the shape to explore
2211 * \param theShapeType - type of subshape of theShape
2212 * \param theState - required state
2213 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2215 //=======================================================================
2216 Handle(TColStd_HSequenceOfInteger)
2217 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
2218 const TopoDS_Shape& theShape,
2219 TopAbs_ShapeEnum theShapeType,
2220 GEOMAlgo_State theState)
2222 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2224 // Check presence of triangulation, build if need
2225 if (!CheckTriangulation(theShape)) {
2226 SetErrorCode("Cannot build triangulation on the shape");
2230 // BEGIN: Mantis issue 0020961: Error on a pipe T-Shape
2231 // Compute tolerance
2232 Standard_Real T, VertMax = -RealLast();
2234 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
2237 for (TopExp_Explorer ExV (theShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
2238 TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
2239 T = BRep_Tool::Tolerance(Vertex);
2244 catch (Standard_Failure) {
2245 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2246 SetErrorCode(aFail->GetMessageString());
2249 // END: Mantis issue 0020961
2252 GEOMAlgo_FinderShapeOn1 aFinder;
2253 //Standard_Real aTol = 0.0001; // default value
2254 Standard_Real aTol = VertMax; // Mantis issue 0020961
2256 aFinder.SetShape(theShape);
2257 aFinder.SetTolerance(aTol);
2258 aFinder.SetSurface(theSurface);
2259 aFinder.SetShapeType(theShapeType);
2260 aFinder.SetState(theState);
2262 // Sets the minimal number of inner points for the faces that do not have own
2263 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2265 aFinder.SetNbPntsMin(3);
2266 // Sets the maximal number of inner points for edges or faces.
2267 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2268 // the performance. If this value =0, all inner points will be taken into account.
2270 aFinder.SetNbPntsMax(100);
2274 // Interprete results
2275 Standard_Integer iErr = aFinder.ErrorStatus();
2276 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2278 MESSAGE(" iErr : " << iErr);
2279 TCollection_AsciiString aMsg (" iErr : ");
2280 aMsg += TCollection_AsciiString(iErr);
2284 Standard_Integer iWrn = aFinder.WarningStatus();
2285 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2287 MESSAGE(" *** iWrn : " << iWrn);
2290 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2292 if (listSS.Extent() < 1) {
2293 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2294 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2298 // Fill sequence of object IDs
2299 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2301 TopTools_IndexedMapOfShape anIndices;
2302 TopExp::MapShapes(theShape, anIndices);
2304 TopTools_ListIteratorOfListOfShape itSub (listSS);
2305 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2306 int id = anIndices.FindIndex(itSub.Value());
2307 aSeqOfIDs->Append(id);
2313 //=======================================================================
2314 //function : getObjectsShapesOn
2316 * \brief Find shape objects and their entries by their ids
2317 * \param theShapeIDs - incoming shape ids
2318 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2319 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
2321 //=======================================================================
2322 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
2323 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
2324 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
2325 TCollection_AsciiString & theShapeEntries)
2327 Handle(TColStd_HSequenceOfTransient) aSeq;
2329 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
2331 aSeq = new TColStd_HSequenceOfTransient;
2332 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
2333 TCollection_AsciiString anEntry;
2334 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
2336 anArray->SetValue(1, theShapeIDs->Value( i ));
2337 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
2338 aSeq->Append( anObj );
2340 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
2341 if ( i != 1 ) theShapeEntries += ",";
2342 theShapeEntries += anEntry;
2348 //=======================================================================
2349 //function : getShapesOnSurface
2351 * \brief Find subshapes complying with given status about surface
2352 * \param theSurface - the surface to check state of subshapes against
2353 * \param theShape - the shape to explore
2354 * \param theShapeType - type of subshape of theShape
2355 * \param theState - required state
2356 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
2357 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2359 //=======================================================================
2360 Handle(TColStd_HSequenceOfTransient)
2361 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
2362 const Handle(GEOM_Object)& theShape,
2363 TopAbs_ShapeEnum theShapeType,
2364 GEOMAlgo_State theState,
2365 TCollection_AsciiString & theShapeEntries)
2367 // Find subshapes ids
2368 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2369 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
2370 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
2373 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
2376 //=============================================================================
2380 //=============================================================================
2381 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
2382 (const Handle(GEOM_Object)& theShape,
2383 const Standard_Integer theShapeType,
2384 const Handle(GEOM_Object)& theAx1,
2385 const GEOMAlgo_State theState)
2389 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2391 TopoDS_Shape aShape = theShape->GetValue();
2392 TopoDS_Shape anAx1 = theAx1->GetValue();
2394 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2396 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2397 if ( !checkTypeShapesOn( theShapeType ))
2401 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2402 if ( aPlane.IsNull() )
2406 TCollection_AsciiString anAsciiList;
2407 Handle(TColStd_HSequenceOfTransient) aSeq;
2408 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2409 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2412 // Make a Python command
2414 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2415 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2417 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2418 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2419 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2425 //=============================================================================
2427 * GetShapesOnPlaneWithLocation
2429 //=============================================================================
2430 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2431 (const Handle(GEOM_Object)& theShape,
2432 const Standard_Integer theShapeType,
2433 const Handle(GEOM_Object)& theAx1,
2434 const Handle(GEOM_Object)& thePnt,
2435 const GEOMAlgo_State theState)
2439 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2441 TopoDS_Shape aShape = theShape->GetValue();
2442 TopoDS_Shape anAx1 = theAx1->GetValue();
2443 TopoDS_Shape anPnt = thePnt->GetValue();
2445 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2447 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2448 if ( !checkTypeShapesOn( theShapeType ))
2452 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2453 TopoDS_Vertex V1, V2, V3;
2454 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2455 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2457 if (V1.IsNull() || V2.IsNull()) {
2458 SetErrorCode("Bad edge given for the plane normal vector");
2461 V3 = TopoDS::Vertex(anPnt);
2464 SetErrorCode("Bad vertex given for the plane location");
2467 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2468 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2470 if (aVec.Magnitude() < Precision::Confusion()) {
2471 SetErrorCode("Vector with null magnitude given");
2474 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2476 if ( aPlane.IsNull() )
2480 TCollection_AsciiString anAsciiList;
2481 Handle(TColStd_HSequenceOfTransient) aSeq;
2482 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2483 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2486 // Make a Python command
2488 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2489 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2491 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2492 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2493 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2499 //=============================================================================
2501 * GetShapesOnCylinder
2503 //=============================================================================
2504 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2505 (const Handle(GEOM_Object)& theShape,
2506 const Standard_Integer theShapeType,
2507 const Handle(GEOM_Object)& theAxis,
2508 const Standard_Real theRadius,
2509 const GEOMAlgo_State theState)
2513 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2515 TopoDS_Shape aShape = theShape->GetValue();
2516 TopoDS_Shape anAxis = theAxis->GetValue();
2518 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2520 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2521 if ( !checkTypeShapesOn( aShapeType ))
2524 // Create a cylinder surface
2525 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2526 if ( aCylinder.IsNull() )
2530 TCollection_AsciiString anAsciiList;
2531 Handle(TColStd_HSequenceOfTransient) aSeq;
2532 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2533 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2536 // Make a Python command
2538 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2539 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2541 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2542 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2543 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2549 //=============================================================================
2551 * GetShapesOnCylinderWithLocation
2553 //=============================================================================
2554 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocation
2555 (const Handle(GEOM_Object)& theShape,
2556 const Standard_Integer theShapeType,
2557 const Handle(GEOM_Object)& theAxis,
2558 const Handle(GEOM_Object)& thePnt,
2559 const Standard_Real theRadius,
2560 const GEOMAlgo_State theState)
2564 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2566 TopoDS_Shape aShape = theShape->GetValue();
2567 TopoDS_Shape anAxis = theAxis->GetValue();
2568 TopoDS_Shape aPnt = thePnt->GetValue();
2570 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2572 if (aPnt.ShapeType() != TopAbs_VERTEX )
2574 SetErrorCode("Bottom location point must be vertex");
2578 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2579 if ( !checkTypeShapesOn( aShapeType ))
2582 // Create a cylinder surface
2583 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2584 if ( aCylinder.IsNull() )
2587 // translate the surface
2588 Handle(Geom_CylindricalSurface) aCylSurface =
2589 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2590 if ( aCylSurface.IsNull() )
2592 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2595 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2596 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2597 aCylinder->Translate( fromLoc, toLoc );
2600 TCollection_AsciiString anAsciiList;
2601 Handle(TColStd_HSequenceOfTransient) aSeq;
2602 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2603 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2606 // Make a Python command
2608 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2609 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2611 GEOM::TPythonDump(aFunction)
2612 << "[" << anAsciiList.ToCString()
2613 << "] = geompy.GetShapesOnCylinderWithLocation(" << theShape << ", " << aShapeType << ", "
2614 << theAxis << ", " << thePnt << ", " << theRadius << ", " << theState << ")";
2620 //=============================================================================
2624 //=============================================================================
2625 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2626 (const Handle(GEOM_Object)& theShape,
2627 const Standard_Integer theShapeType,
2628 const Handle(GEOM_Object)& theCenter,
2629 const Standard_Real theRadius,
2630 const GEOMAlgo_State theState)
2634 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2636 TopoDS_Shape aShape = theShape->GetValue();
2637 TopoDS_Shape aCenter = theCenter->GetValue();
2639 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2641 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2642 if ( !checkTypeShapesOn( aShapeType ))
2645 // Center of the sphere
2646 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2647 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2649 gp_Ax3 anAx3 (aLoc, gp::DZ());
2650 Handle(Geom_SphericalSurface) aSphere =
2651 new Geom_SphericalSurface(anAx3, theRadius);
2654 TCollection_AsciiString anAsciiList;
2655 Handle(TColStd_HSequenceOfTransient) aSeq;
2656 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2657 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2660 // Make a Python command
2662 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2663 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2665 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2666 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2667 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2673 //=============================================================================
2675 * GetShapesOnPlaneIDs
2677 //=============================================================================
2678 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2679 (const Handle(GEOM_Object)& theShape,
2680 const Standard_Integer theShapeType,
2681 const Handle(GEOM_Object)& theAx1,
2682 const GEOMAlgo_State theState)
2686 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2688 TopoDS_Shape aShape = theShape->GetValue();
2689 TopoDS_Shape anAx1 = theAx1->GetValue();
2691 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2693 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2694 if ( !checkTypeShapesOn( aShapeType ))
2698 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2699 if ( aPlane.IsNull() )
2703 Handle(TColStd_HSequenceOfInteger) aSeq;
2704 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2706 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2707 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2709 // Make a Python command
2710 GEOM::TPythonDump(aFunction, /*append=*/true)
2711 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2712 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2718 //=============================================================================
2720 * GetShapesOnPlaneWithLocationIDs
2722 //=============================================================================
2723 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2724 (const Handle(GEOM_Object)& theShape,
2725 const Standard_Integer theShapeType,
2726 const Handle(GEOM_Object)& theAx1,
2727 const Handle(GEOM_Object)& thePnt,
2728 const GEOMAlgo_State theState)
2732 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2734 TopoDS_Shape aShape = theShape->GetValue();
2735 TopoDS_Shape anAx1 = theAx1->GetValue();
2736 TopoDS_Shape anPnt = thePnt->GetValue();
2738 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2740 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2741 if ( !checkTypeShapesOn( aShapeType ))
2745 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2746 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2747 TopoDS_Vertex V1, V2, V3;
2748 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2749 if (V1.IsNull() || V2.IsNull()) {
2750 SetErrorCode("Bad edge given for the plane normal vector");
2753 V3 = TopoDS::Vertex(anPnt);
2755 SetErrorCode("Bad vertex given for the plane location");
2758 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2759 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2760 if (aVec.Magnitude() < Precision::Confusion()) {
2761 SetErrorCode("Vector with null magnitude given");
2765 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2766 if ( aPlane.IsNull() )
2770 Handle(TColStd_HSequenceOfInteger) aSeq;
2771 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2773 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2774 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2776 // Make a Python command
2777 GEOM::TPythonDump(aFunction, /*append=*/true)
2778 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2779 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2785 //=============================================================================
2787 * GetShapesOnCylinderIDs
2789 //=============================================================================
2790 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2791 (const Handle(GEOM_Object)& theShape,
2792 const Standard_Integer theShapeType,
2793 const Handle(GEOM_Object)& theAxis,
2794 const Standard_Real theRadius,
2795 const GEOMAlgo_State theState)
2799 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2801 TopoDS_Shape aShape = theShape->GetValue();
2802 TopoDS_Shape anAxis = theAxis->GetValue();
2804 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2806 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2807 if ( !checkTypeShapesOn( aShapeType ))
2810 // Create a cylinder surface
2811 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2812 if ( aCylinder.IsNull() )
2816 Handle(TColStd_HSequenceOfInteger) aSeq;
2817 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2819 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2820 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2822 // Make a Python command
2823 GEOM::TPythonDump(aFunction, /*append=*/true)
2824 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2825 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2826 << theRadius << ", " << theState << ")";
2832 //=============================================================================
2834 * GetShapesOnCylinderWithLocationIDs
2836 //=============================================================================
2837 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderWithLocationIDs
2838 (const Handle(GEOM_Object)& theShape,
2839 const Standard_Integer theShapeType,
2840 const Handle(GEOM_Object)& theAxis,
2841 const Handle(GEOM_Object)& thePnt,
2842 const Standard_Real theRadius,
2843 const GEOMAlgo_State theState)
2847 if (theShape.IsNull() || theAxis.IsNull() || thePnt.IsNull()) return NULL;
2849 TopoDS_Shape aShape = theShape->GetValue();
2850 TopoDS_Shape anAxis = theAxis->GetValue();
2851 TopoDS_Shape aPnt = thePnt->GetValue();
2853 if (aShape.IsNull() || anAxis.IsNull() || aPnt.IsNull()) return NULL;
2855 if (aPnt.ShapeType() != TopAbs_VERTEX )
2857 SetErrorCode("Bottom location point must be vertex");
2861 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2862 if ( !checkTypeShapesOn( aShapeType ))
2865 // Create a cylinder surface
2866 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2867 if ( aCylinder.IsNull() )
2870 // translate the surface
2871 Handle(Geom_CylindricalSurface) aCylSurface =
2872 Handle(Geom_CylindricalSurface)::DownCast( aCylinder );
2873 if ( aCylSurface.IsNull() )
2875 SetErrorCode("Unexpected surface type instead of Geom_CylindricalSurface");
2878 gp_Pnt fromLoc = aCylSurface->Cylinder().Location();
2879 gp_Pnt toLoc = BRep_Tool::Pnt( TopoDS::Vertex( aPnt ));
2880 aCylinder->Translate( fromLoc, toLoc );
2883 Handle(TColStd_HSequenceOfInteger) aSeq;
2884 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2886 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2887 Handle(GEOM_Function) aFunction =
2888 GEOM::GetCreatedLast(theShape, GEOM::GetCreatedLast(thePnt,theAxis))->GetLastFunction();
2890 // Make a Python command
2891 GEOM::TPythonDump(aFunction, /*append=*/true)
2892 << "listShapesOnCylinder = geompy.GetShapesOnCylinderWithLocationIDs"
2893 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2894 << thePnt << ", " << theRadius << ", " << theState << ")";
2900 //=============================================================================
2902 * GetShapesOnSphereIDs
2904 //=============================================================================
2905 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2906 (const Handle(GEOM_Object)& theShape,
2907 const Standard_Integer theShapeType,
2908 const Handle(GEOM_Object)& theCenter,
2909 const Standard_Real theRadius,
2910 const GEOMAlgo_State theState)
2914 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2916 TopoDS_Shape aShape = theShape->GetValue();
2917 TopoDS_Shape aCenter = theCenter->GetValue();
2919 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2921 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2922 if ( !checkTypeShapesOn( aShapeType ))
2925 // Center of the sphere
2926 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2927 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2929 gp_Ax3 anAx3 (aLoc, gp::DZ());
2930 Handle(Geom_SphericalSurface) aSphere =
2931 new Geom_SphericalSurface(anAx3, theRadius);
2934 Handle(TColStd_HSequenceOfInteger) aSeq;
2935 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2937 // The GetShapesOnSphere() doesn't change object so no new function is required.
2938 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2940 // Make a Python command
2941 GEOM::TPythonDump(aFunction, /*append=*/true)
2942 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2943 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2944 << theRadius << ", " << theState << ")";
2950 //=======================================================================
2951 //function : getShapesOnQuadrangleIDs
2953 * \brief Find IDs of subshapes complying with given status about quadrangle
2954 * \param theShape - the shape to explore
2955 * \param theShapeType - type of subshape of theShape
2956 * \param theTopLeftPoint - top left quadrangle corner
2957 * \param theTopRigthPoint - top right quadrangle corner
2958 * \param theBottomLeftPoint - bottom left quadrangle corner
2959 * \param theBottomRigthPoint - bottom right quadrangle corner
2960 * \param theState - required state
2961 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2963 //=======================================================================
2964 Handle(TColStd_HSequenceOfInteger)
2965 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2966 const Standard_Integer theShapeType,
2967 const Handle(GEOM_Object)& theTopLeftPoint,
2968 const Handle(GEOM_Object)& theTopRigthPoint,
2969 const Handle(GEOM_Object)& theBottomLeftPoint,
2970 const Handle(GEOM_Object)& theBottomRigthPoint,
2971 const GEOMAlgo_State theState)
2975 if ( theShape.IsNull() ||
2976 theTopLeftPoint.IsNull() ||
2977 theTopRigthPoint.IsNull() ||
2978 theBottomLeftPoint.IsNull() ||
2979 theBottomRigthPoint.IsNull() )
2982 TopoDS_Shape aShape = theShape->GetValue();
2983 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2984 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2985 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2986 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2988 if (aShape.IsNull() ||
2993 aTL.ShapeType() != TopAbs_VERTEX ||
2994 aTR.ShapeType() != TopAbs_VERTEX ||
2995 aBL.ShapeType() != TopAbs_VERTEX ||
2996 aBR.ShapeType() != TopAbs_VERTEX )
2999 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
3000 if ( !checkTypeShapesOn( aShapeType ))
3003 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
3005 // Check presence of triangulation, build if need
3006 if (!CheckTriangulation(aShape)) {
3007 SetErrorCode("Cannot build triangulation on the shape");
3012 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
3013 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
3014 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
3015 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
3017 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
3018 Standard_Real aTol = 0.0001; // default value
3020 aFinder.SetShape(aShape);
3021 aFinder.SetTolerance(aTol);
3022 //aFinder.SetSurface(theSurface);
3023 aFinder.SetShapeType(aShapeType);
3024 aFinder.SetState(theState);
3026 // Sets the minimal number of inner points for the faces that do not have own
3027 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
3029 aFinder.SetNbPntsMin(3);
3030 // Sets the maximal number of inner points for edges or faces.
3031 // It is usefull for the cases when this number is very big (e.g =2000) to improve
3032 // the performance. If this value =0, all inner points will be taken into account.
3034 aFinder.SetNbPntsMax(100);
3038 // Interprete results
3039 Standard_Integer iErr = aFinder.ErrorStatus();
3040 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
3042 MESSAGE(" iErr : " << iErr);
3043 TCollection_AsciiString aMsg (" iErr : ");
3044 aMsg += TCollection_AsciiString(iErr);
3048 Standard_Integer iWrn = aFinder.WarningStatus();
3049 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
3051 MESSAGE(" *** iWrn : " << iWrn);
3054 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
3056 if (listSS.Extent() < 1) {
3057 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
3058 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
3062 // Fill sequence of object IDs
3063 aSeqOfIDs = new TColStd_HSequenceOfInteger;
3065 TopTools_IndexedMapOfShape anIndices;
3066 TopExp::MapShapes(aShape, anIndices);
3068 TopTools_ListIteratorOfListOfShape itSub (listSS);
3069 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
3070 int id = anIndices.FindIndex(itSub.Value());
3071 aSeqOfIDs->Append(id);
3076 //=======================================================================
3077 //function : GetShapesOnQuadrangle
3079 * \brief Find subshapes complying with given status about quadrangle
3080 * \param theShape - the shape to explore
3081 * \param theShapeType - type of subshape of theShape
3082 * \param theTopLeftPoint - top left quadrangle corner
3083 * \param theTopRigthPoint - top right quadrangle corner
3084 * \param theBottomLeftPoint - bottom left quadrangle corner
3085 * \param theBottomRigthPoint - bottom right quadrangle corner
3086 * \param theState - required state
3087 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3089 //=======================================================================
3090 Handle(TColStd_HSequenceOfTransient)
3091 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
3092 const Standard_Integer theShapeType,
3093 const Handle(GEOM_Object)& theTopLeftPoint,
3094 const Handle(GEOM_Object)& theTopRigthPoint,
3095 const Handle(GEOM_Object)& theBottomLeftPoint,
3096 const Handle(GEOM_Object)& theBottomRigthPoint,
3097 const GEOMAlgo_State theState)
3100 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3101 getShapesOnQuadrangleIDs( theShape,
3106 theBottomRigthPoint,
3108 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3111 // Find objects by indices
3112 TCollection_AsciiString anAsciiList;
3113 Handle(TColStd_HSequenceOfTransient) aSeq;
3114 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
3115 if ( aSeq.IsNull() || aSeq->IsEmpty() )
3118 // Make a Python command
3120 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
3121 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
3123 GEOM::TPythonDump(aFunction)
3124 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
3126 << TopAbs_ShapeEnum(theShapeType) << ", "
3127 << theTopLeftPoint << ", "
3128 << theTopRigthPoint << ", "
3129 << theBottomLeftPoint << ", "
3130 << theBottomRigthPoint << ", "
3137 //=======================================================================
3138 //function : GetShapesOnQuadrangleIDs
3140 * \brief Find IDs of subshapes complying with given status about quadrangle
3141 * \param theShape - the shape to explore
3142 * \param theShapeType - type of subshape of theShape
3143 * \param theTopLeftPoint - top left quadrangle corner
3144 * \param theTopRigthPoint - top right quadrangle corner
3145 * \param theBottomLeftPoint - bottom left quadrangle corner
3146 * \param theBottomRigthPoint - bottom right quadrangle corner
3147 * \param theState - required state
3148 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
3150 //=======================================================================
3151 Handle(TColStd_HSequenceOfInteger)
3152 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
3153 const Standard_Integer theShapeType,
3154 const Handle(GEOM_Object)& theTopLeftPoint,
3155 const Handle(GEOM_Object)& theTopRigthPoint,
3156 const Handle(GEOM_Object)& theBottomLeftPoint,
3157 const Handle(GEOM_Object)& theBottomRigthPoint,
3158 const GEOMAlgo_State theState)
3161 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
3162 getShapesOnQuadrangleIDs( theShape,
3167 theBottomRigthPoint,
3169 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
3172 // Make a Python command
3174 // The GetShapesOnCylinder() doesn't change object so no new function is required.
3175 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
3176 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
3177 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
3178 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
3179 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
3181 GEOM::TPythonDump(aFunction, /*append=*/true)
3182 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
3184 << TopAbs_ShapeEnum(theShapeType) << ", "
3185 << theTopLeftPoint << ", "
3186 << theTopRigthPoint << ", "
3187 << theBottomLeftPoint << ", "
3188 << theBottomRigthPoint << ", "
3195 //=============================================================================
3199 //=============================================================================
3200 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
3201 const TopTools_IndexedMapOfShape& theWhereIndices,
3202 const TopoDS_Shape& theWhat,
3203 TColStd_ListOfInteger& theModifiedList)
3205 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
3207 if (theWhereIndices.Contains(theWhat)) {
3208 // entity was not changed by the operation
3209 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
3210 theModifiedList.Append(aWhatIndex);
3214 // try to find in history
3215 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
3217 // search in history for all argument shapes
3218 Standard_Boolean isFound = Standard_False;
3219 Standard_Boolean isGood = Standard_False;
3221 TDF_LabelSequence aLabelSeq;
3222 theWhereFunction->GetDependency(aLabelSeq);
3223 Standard_Integer nbArg = aLabelSeq.Length();
3225 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
3227 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
3229 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
3230 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
3232 TopTools_IndexedMapOfShape anArgumentIndices;
3233 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
3235 if (anArgumentIndices.Contains(theWhat)) {
3236 isFound = Standard_True;
3237 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
3239 // Find corresponding label in history
3240 TDF_Label anArgumentHistoryLabel =
3241 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
3242 if (anArgumentHistoryLabel.IsNull()) {
3243 // Lost History of operation argument. Possibly, all its entities was removed.
3244 isGood = Standard_True;
3247 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
3249 if (aWhatHistoryLabel.IsNull()) {
3250 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
3251 isGood = Standard_False;
3253 Handle(TDataStd_IntegerArray) anIntegerArray;
3254 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
3255 //Error: Empty modifications history for the sought shape.
3256 isGood = Standard_False;
3259 isGood = Standard_True;
3260 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
3261 for (imod = 1; imod <= aModifLen; imod++) {
3262 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
3273 // try compound/compsolid/shell/wire element by element
3274 bool isFoundAny = false;
3275 TopTools_MapOfShape mapShape;
3277 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
3278 theWhat.ShapeType() == TopAbs_COMPSOLID) {
3279 // recursive processing of compound/compsolid
3280 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
3281 for (; anIt.More(); anIt.Next()) {
3282 if (mapShape.Add(anIt.Value())) {
3283 TopoDS_Shape curWhat = anIt.Value();
3284 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3285 if (isFoundAny) isFound = Standard_True;
3289 else if (theWhat.ShapeType() == TopAbs_SHELL) {
3290 // try to replace a shell by its faces images
3291 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
3292 for (; anExp.More(); anExp.Next()) {
3293 if (mapShape.Add(anExp.Current())) {
3294 TopoDS_Shape curWhat = anExp.Current();
3295 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3296 if (isFoundAny) isFound = Standard_True;
3300 else if (theWhat.ShapeType() == TopAbs_WIRE) {
3301 // try to replace a wire by its edges images
3302 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
3303 for (; anExp.More(); anExp.Next()) {
3304 if (mapShape.Add(anExp.Current())) {
3305 TopoDS_Shape curWhat = anExp.Current();
3306 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
3307 if (isFoundAny) isFound = Standard_True;
3319 //=============================================================================
3321 * GetShapeProperties
3323 //=============================================================================
3324 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
3327 GProp_GProps theProps;
3329 //TopoDS_Shape aPntShape;
3330 Standard_Real aShapeSize;
3332 if (aShape.ShapeType() == TopAbs_VERTEX) aCenterMass = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
3333 else if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
3334 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
3335 else BRepGProp::VolumeProperties(aShape, theProps);
3337 if (aShape.ShapeType() == TopAbs_VERTEX)
3340 aCenterMass = theProps.CentreOfMass();
3341 aShapeSize = theProps.Mass();
3344 // aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
3345 // aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
3346 aVertex = aCenterMass;
3347 tab[0] = aVertex.X();
3348 tab[1] = aVertex.Y();
3349 tab[2] = aVertex.Z();
3350 tab[3] = aShapeSize;
3356 //================================================================================
3358 * \brief Return normal to face at extrema point
3360 //================================================================================
3362 gp_Vec GetNormal (const TopoDS_Face& face, const BRepExtrema_DistShapeShape& extrema)
3364 gp_Vec defaultNorm(1,0,0); // to have same normals on different faces
3366 // get UV at extrema point
3367 Standard_Real u,v, f,l;
3368 switch ( extrema.SupportTypeShape2(1) ) {
3369 case BRepExtrema_IsInFace: {
3370 extrema.ParOnFaceS2(1, u, v );
3373 case BRepExtrema_IsOnEdge: {
3374 TopoDS_Edge edge = TopoDS::Edge( extrema.SupportOnShape2(1));
3375 Handle(Geom2d_Curve) pcurve = BRep_Tool::CurveOnSurface( edge, face, f,l );
3376 extrema.ParOnEdgeS2( 1, u );
3377 gp_Pnt2d uv = pcurve->Value( u );
3382 case BRepExtrema_IsVertex: return defaultNorm;
3385 BRepAdaptor_Surface surface( face, false );
3386 gp_Vec du, dv; gp_Pnt p;
3387 surface.D1( u, v, p, du, dv );
3391 } catch (Standard_Failure ) {
3396 //================================================================================
3398 * \brief Return type of shape for explode. In case of compound it will be a type of sub shape.
3400 //================================================================================
3402 TopAbs_ShapeEnum GetTypeOfSimplePart (const TopoDS_Shape& theShape)
3404 TopAbs_ShapeEnum aType = theShape.ShapeType();
3405 if (aType == TopAbs_VERTEX) return TopAbs_VERTEX;
3406 else if (aType == TopAbs_EDGE || aType == TopAbs_WIRE) return TopAbs_EDGE;
3407 else if (aType == TopAbs_FACE || aType == TopAbs_SHELL) return TopAbs_FACE;
3408 else if (aType == TopAbs_SOLID || aType == TopAbs_COMPSOLID) return TopAbs_SOLID;
3409 else if (aType == TopAbs_COMPOUND) {
3410 // Only the iType of the first shape in the compound is taken into account
3411 TopoDS_Iterator It (theShape, Standard_False, Standard_False);
3413 return GetTypeOfSimplePart(It.Value());
3416 return TopAbs_SHAPE;
3420 //=============================================================================
3425 //=============================================================================
3426 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
3427 Handle(GEOM_Object) theShapeWhat)
3431 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3433 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3434 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3435 TopoDS_Shape aPntShape;
3436 TopoDS_Vertex aVertex;
3438 if (aWhere.IsNull() || aWhat.IsNull()) {
3439 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
3443 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3444 if (aWhereFunction.IsNull()) {
3445 SetErrorCode("Error: aWhereFunction is Null.");
3449 TopTools_IndexedMapOfShape aWhereIndices;
3450 TopExp::MapShapes(aWhere, aWhereIndices);
3452 TColStd_ListOfInteger aModifiedList;
3453 Standard_Integer aWhereIndex;
3454 Handle(TColStd_HArray1OfInteger) aModifiedArray;
3455 Handle(GEOM_Object) aResult;
3457 bool isFound = false;
3458 TopAbs_ShapeEnum iType = TopAbs_SOLID;
3459 //Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
3460 Standard_Real tab_aWhat[4], tab_aWhere[4];
3461 Standard_Real dl_l = 1e-3;
3462 Standard_Real min_l, Tol_0D, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
3463 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3464 Bnd_Box BoundingBox;
3465 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
3466 GProp_GProps aProps;
3468 // Find the iType of the aWhat shape
3470 if ( aWhat.ShapeType() == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3471 else if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
3472 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
3473 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
3474 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
3475 // Only the iType of the first shape in the compound is taken into account
3476 TopoDS_Iterator It (aWhat, Standard_False, Standard_False);
3478 SetErrorCode("Error: theShapeWhat is an empty COMPOUND.");
3481 TopAbs_ShapeEnum compType = It.Value().ShapeType();
3482 if ( compType == TopAbs_VERTEX ) iType = TopAbs_VERTEX;
3483 else if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
3484 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
3485 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
3488 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3492 iType = GetTypeOfSimplePart(aWhat);
3493 if (iType == TopAbs_SHAPE) {
3494 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
3498 TopExp_Explorer Exp_aWhat ( aWhat, iType );
3499 TopExp_Explorer Exp_aWhere ( aWhere, iType );
3500 TopExp_Explorer Exp_Edge ( aWhere, TopAbs_EDGE );
3502 // Find the shortest edge in theShapeWhere shape
3503 BRepBndLib::Add(aWhere, BoundingBox);
3504 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3505 min_l = fabs(aXmax - aXmin);
3506 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
3507 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
3509 // Mantis issue 0020908 BEGIN
3510 if (!Exp_Edge.More()) {
3511 min_l = Precision::Confusion();
3513 // Mantis issue 0020908 END
3514 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
3515 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
3516 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
3517 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
3518 tab_Pnt[nbVertex] = aPnt;
3520 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
3521 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
3522 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
3526 // Compute tolerances
3528 Tol_1D = dl_l * min_l;
3529 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
3530 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
3532 if (Tol_0D < Precision::Confusion()) Tol_0D = Precision::Confusion();
3533 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
3534 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
3535 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
3537 //if (Tol_1D > 1.0) Tol_1D = 1.0;
3538 //if (Tol_2D > 1.0) Tol_2D = 1.0;
3539 //if (Tol_3D > 1.0) Tol_3D = 1.0;
3542 if ( iType == TopAbs_VERTEX ) Tol_Mass = Tol_0D;
3543 else if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
3544 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
3546 // Compute the ShapeWhat Mass
3548 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
3549 if ( iType == TopAbs_VERTEX ) {
3553 else if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
3554 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
3555 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
3556 aWhat_Mass += aProps.Mass();
3560 // Searching for the sub-shapes inside the ShapeWhere shape
3561 TopTools_MapOfShape map_aWhere;
3562 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
3563 if (!map_aWhere.Add(Exp_aWhere.Current()))
3564 continue; // skip repeated shape to avoid mass addition
3565 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
3566 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
3567 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
3568 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
3571 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
3572 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
3573 aVertex = TopoDS::Vertex( aPntShape );
3574 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
3575 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
3576 if ( aWhereDistance.IsDone() && aWhatDistance.IsDone() &&
3577 fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
3579 // 0020162: "EDF 961 GEOM : Getinplace is getting additionnal orthogonal faces"
3580 // aVertex must be projected to the same point on Where and on What
3581 gp_Pnt pOnWhat = aWhatDistance.PointOnShape2(1);
3582 gp_Pnt pOnWhere = aWhereDistance.PointOnShape2(1);
3583 isFound = ( pOnWhat.Distance(pOnWhere) <= Tol_1D );
3584 if ( isFound && iType == TopAbs_FACE )
3586 // check normals at pOnWhat and pOnWhere
3587 const double angleTol = PI/180.;
3588 gp_Vec normToWhat = GetNormal( TopoDS::Face(Exp_aWhat.Current()), aWhatDistance);
3589 gp_Vec normToWhere = GetNormal( TopoDS::Face(Exp_aWhere.Current()), aWhereDistance);
3590 if ( normToWhat * normToWhere < 0 )
3591 normToWhat.Reverse();
3592 isFound = ( normToWhat.Angle( normToWhere ) < angleTol );
3598 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
3599 aModifiedList.Append(aWhereIndex);
3600 //aWhere_Mass += tab_aWhere[3];
3605 //if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass )
3609 if (aModifiedList.Extent() == 0) { // Not found any Results
3610 SetErrorCode(NOT_FOUND_ANY);
3614 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3615 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3616 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
3617 aModifiedArray->SetValue(imod, anIterModif.Value());
3620 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3621 if (aResult.IsNull()) {
3622 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3626 if (aModifiedArray->Length() > 1) {
3628 aResult->SetType(GEOM_GROUP);
3630 //Set a sub shape type
3631 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3632 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3634 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3635 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3638 //Make a Python command
3639 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3641 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
3642 << theShapeWhere << ", " << theShapeWhat << ")";
3648 //=======================================================================
3649 //function : GetInPlaceByHistory
3651 //=======================================================================
3652 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
3653 (Handle(GEOM_Object) theShapeWhere,
3654 Handle(GEOM_Object) theShapeWhat)
3658 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3660 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3661 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3663 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3665 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
3666 if (aWhereFunction.IsNull()) return NULL;
3668 //Fill array of indices
3669 TopTools_IndexedMapOfShape aWhereIndices;
3670 TopExp::MapShapes(aWhere, aWhereIndices);
3673 TColStd_ListOfInteger aModifiedList;
3674 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3676 if (!isFound || aModifiedList.Extent() < 1) {
3677 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3681 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3682 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3683 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3684 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3685 aModifiedArray->SetValue(imod, anIterModif.Value());
3689 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3690 if (aResult.IsNull()) {
3691 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3695 if (aModifiedArray->Length() > 1) {
3697 aResult->SetType(GEOM_GROUP);
3699 //Set a sub shape type
3700 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3701 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3703 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3704 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3707 //Make a Python command
3708 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3710 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
3711 << theShapeWhere << ", " << theShapeWhat << ")";
3717 //=======================================================================
3718 //function : SortShapes
3720 //=======================================================================
3721 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL,
3722 const Standard_Boolean isOldSorting)
3724 Standard_Integer MaxShapes = SL.Extent();
3725 TopTools_Array1OfShape aShapes (1,MaxShapes);
3726 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3727 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3728 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3730 // Computing of CentreOfMass
3731 Standard_Integer Index;
3734 TopTools_ListIteratorOfListOfShape it(SL);
3735 for (Index=1; it.More(); Index++)
3737 TopoDS_Shape S = it.Value();
3738 SL.Remove( it ); // == it.Next()
3740 OrderInd.SetValue (Index, Index);
3741 if (S.ShapeType() == TopAbs_VERTEX) {
3742 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3743 Length.SetValue( Index, (Standard_Real) S.Orientation());
3746 // BEGIN: fix for Mantis issue 0020842
3748 BRepGProp::LinearProperties (S, GPr);
3751 if (S.ShapeType() == TopAbs_EDGE || S.ShapeType() == TopAbs_WIRE) {
3752 BRepGProp::LinearProperties (S, GPr);
3754 else if (S.ShapeType() == TopAbs_FACE || S.ShapeType() == TopAbs_SHELL) {
3755 BRepGProp::SurfaceProperties(S, GPr);
3758 BRepGProp::VolumeProperties(S, GPr);
3761 // END: fix for Mantis issue 0020842
3762 GPoint = GPr.CentreOfMass();
3763 Length.SetValue(Index, GPr.Mass());
3765 MidXYZ.SetValue(Index,
3766 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3767 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3771 Standard_Integer aTemp;
3772 Standard_Boolean exchange, Sort = Standard_True;
3773 Standard_Real tol = Precision::Confusion();
3776 Sort = Standard_False;
3777 for (Index=1; Index < MaxShapes; Index++)
3779 exchange = Standard_False;
3780 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3781 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3782 if ( dMidXYZ >= tol ) {
3783 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3784 // << " d: " << dMidXYZ << endl;
3785 exchange = Standard_True;
3787 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3788 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3789 // << " d: " << dLength << endl;
3790 exchange = Standard_True;
3792 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3793 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3795 // equal values possible on shapes such as two halves of a sphere and
3796 // a membrane inside the sphere
3798 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3799 if ( box1.IsVoid() ) continue;
3800 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3801 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3802 if ( dSquareExtent >= tol ) {
3803 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3804 exchange = Standard_True;
3806 else if ( Abs(dSquareExtent) < tol ) {
3807 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3808 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3809 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3810 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3811 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3812 //exchange = val1 > val2;
3813 if ((val1 - val2) >= tol) {
3814 exchange = Standard_True;
3816 //cout << "box: " << val1<<" > "<<val2 << endl;
3822 // cout << "exchange " << Index << " & " << Index+1 << endl;
3823 aTemp = OrderInd(Index);
3824 OrderInd(Index) = OrderInd(Index+1);
3825 OrderInd(Index+1) = aTemp;
3826 Sort = Standard_True;
3831 for (Index=1; Index <= MaxShapes; Index++)
3832 SL.Append( aShapes( OrderInd(Index) ));
3835 //=======================================================================
3836 //function : CompsolidToCompound
3838 //=======================================================================
3839 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3841 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3842 return theCompsolid;
3845 TopoDS_Compound aCompound;
3847 B.MakeCompound(aCompound);
3849 TopTools_MapOfShape mapShape;
3850 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3852 for (; It.More(); It.Next()) {
3853 TopoDS_Shape aShape_i = It.Value();
3854 if (mapShape.Add(aShape_i)) {
3855 B.Add(aCompound, aShape_i);
3862 //=======================================================================
3863 //function : CheckTriangulation
3865 //=======================================================================
3866 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3868 bool isTriangulation = true;
3870 TopExp_Explorer exp (aShape, TopAbs_FACE);
3873 TopLoc_Location aTopLoc;
3874 Handle(Poly_Triangulation) aTRF;
3875 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3876 if (aTRF.IsNull()) {
3877 isTriangulation = false;
3880 else // no faces, try edges
3882 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3886 TopLoc_Location aLoc;
3887 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3889 isTriangulation = false;
3893 if (!isTriangulation) {
3894 // calculate deflection
3895 Standard_Real aDeviationCoefficient = 0.001;
3898 BRepBndLib::Add(aShape, B);
3899 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3900 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3902 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3903 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3904 Standard_Real aHLRAngle = 0.349066;
3906 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3912 #define MAX_TOLERANCE 1.e-7
3914 //=======================================================================
3915 //function : isSameEdge
3916 //purpose : Returns True if two edges coincide
3917 //=======================================================================
3918 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3920 TopoDS_Vertex V11, V12, V21, V22;
3921 TopExp::Vertices(theEdge1, V11, V12);
3922 TopExp::Vertices(theEdge2, V21, V22);
3923 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3924 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3925 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3926 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3927 bool coincide = false;
3929 //Check that ends of edges coincide
3930 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3931 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3933 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3934 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3937 if(!coincide) return false;
3939 if (BRep_Tool::Degenerated(theEdge1))
3940 if (BRep_Tool::Degenerated(theEdge2)) return true;
3943 if (BRep_Tool::Degenerated(theEdge2)) return false;
3945 double U11, U12, U21, U22;
3946 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3947 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3948 if(C1->DynamicType() == C2->DynamicType()) return true;
3950 //Check that both edges has the same geometry
3951 double range = U12-U11;
3952 double U = U11+ range/3.0;
3953 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3954 U = U11+range*2.0/3.0;
3955 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3957 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3960 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3962 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3965 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3970 #include <TopoDS_TShape.hxx>
3971 //=======================================================================
3972 //function : isSameFace
3973 //purpose : Returns True if two faces coincide
3974 //=======================================================================
3975 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3977 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3978 TopTools_ListOfShape LS1, LS2;
3979 for(; E.More(); E.Next()) LS1.Append(E.Current());
3981 E.Init(theFace2, TopAbs_EDGE);
3982 for(; E.More(); E.Next()) LS2.Append(E.Current());
3984 //Compare the number of edges in the faces
3985 if(LS1.Extent() != LS2.Extent()) return false;
3987 double aMin = RealFirst(), aMax = RealLast();
3988 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3989 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3991 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3992 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3993 if(P.X() < xminB1) xminB1 = P.X();
3994 if(P.Y() < yminB1) yminB1 = P.Y();
3995 if(P.Z() < zminB1) zminB1 = P.Z();
3996 if(P.X() > xmaxB1) xmaxB1 = P.X();
3997 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3998 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4001 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
4002 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4003 if(P.X() < xminB2) xminB2 = P.X();
4004 if(P.Y() < yminB2) yminB2 = P.Y();
4005 if(P.Z() < zminB2) zminB2 = P.Z();
4006 if(P.X() > xmaxB2) xmaxB2 = P.X();
4007 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4008 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4011 //Compare the bounding boxes of both faces
4012 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4015 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4018 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
4019 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
4021 //Check if there a coincidence of two surfaces at least in two points
4022 double U11, U12, V11, V12, U21, U22, V21, V22;
4023 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
4024 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
4026 double rangeU = U12-U11;
4027 double rangeV = V12-V11;
4028 double U = U11 + rangeU/3.0;
4029 double V = V11 + rangeV/3.0;
4030 gp_Pnt P1 = S1->Value(U, V);
4031 U = U11+rangeU*2.0/3.0;
4032 V = V11+rangeV*2.0/3.0;
4033 gp_Pnt P2 = S1->Value(U, V);
4035 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4038 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
4040 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
4043 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
4045 //Check that each edge of the Face1 has a counterpart in the Face2
4046 TopTools_MapOfOrientedShape aMap;
4047 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4048 for(; LSI1.More(); LSI1.Next()) {
4049 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
4050 bool isFound = false;
4051 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4052 for(; LSI2.More(); LSI2.Next()) {
4053 TopoDS_Shape aValue = LSI2.Value();
4054 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
4055 if(isSameEdge(E, TopoDS::Edge(aValue))) {
4061 if(!isFound) return false;
4067 //=======================================================================
4068 //function : isSameSolid
4069 //purpose : Returns True if two solids coincide
4070 //=======================================================================
4071 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
4073 TopExp_Explorer E(theSolid1, TopAbs_FACE);
4074 TopTools_ListOfShape LS1, LS2;
4075 for(; E.More(); E.Next()) LS1.Append(E.Current());
4076 E.Init(theSolid2, TopAbs_FACE);
4077 for(; E.More(); E.Next()) LS2.Append(E.Current());
4079 if(LS1.Extent() != LS2.Extent()) return false;
4081 double aMin = RealFirst(), aMax = RealLast();
4082 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
4083 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
4085 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
4086 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4087 if(P.X() < xminB1) xminB1 = P.X();
4088 if(P.Y() < yminB1) yminB1 = P.Y();
4089 if(P.Z() < zminB1) zminB1 = P.Z();
4090 if(P.X() > xmaxB1) xmaxB1 = P.X();
4091 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
4092 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
4095 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
4096 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4097 if(P.X() < xminB2) xminB2 = P.X();
4098 if(P.Y() < yminB2) yminB2 = P.Y();
4099 if(P.Z() < zminB2) zminB2 = P.Z();
4100 if(P.X() > xmaxB2) xmaxB2 = P.X();
4101 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
4102 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
4105 //Compare the bounding boxes of both solids
4106 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
4109 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
4112 //Check that each face of the Solid1 has a counterpart in the Solid2
4113 TopTools_MapOfOrientedShape aMap;
4114 TopTools_ListIteratorOfListOfShape LSI1(LS1);
4115 for(; LSI1.More(); LSI1.Next()) {
4116 TopoDS_Face F = TopoDS::Face(LSI1.Value());
4117 bool isFound = false;
4118 TopTools_ListIteratorOfListOfShape LSI2(LS2);
4119 for(; LSI2.More(); LSI2.Next()) {
4120 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
4121 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
4122 aMap.Add(LSI2.Value());
4127 if(!isFound) return false;
4133 //=======================================================================
4134 //function : GetSame
4136 //=======================================================================
4137 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
4138 const Handle(GEOM_Object)& theShapeWhat)
4141 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
4143 TopoDS_Shape aWhere = theShapeWhere->GetValue();
4144 TopoDS_Shape aWhat = theShapeWhat->GetValue();
4146 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
4149 bool isFound = false;
4150 TopoDS_Shape aSubShape;
4151 TopTools_MapOfShape aMap;
4153 if (aWhat.ShapeType() == TopAbs_COMPOUND || aWhat.ShapeType() == TopAbs_COMPSOLID) {
4154 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
4155 if (It.More()) aWhat = It.Value();
4158 SetErrorCode("Compounds of two or more shapes are not allowed for aWhat argument");
4163 switch (aWhat.ShapeType()) {
4164 case TopAbs_VERTEX: {
4165 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
4166 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
4167 for(; E.More(); E.Next()) {
4168 if(!aMap.Add(E.Current())) continue;
4169 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
4170 if(P.Distance(P2) <= MAX_TOLERANCE) {
4172 aSubShape = E.Current();
4179 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
4180 TopExp_Explorer E(aWhere, TopAbs_EDGE);
4181 for(; E.More(); E.Next()) {
4182 if(!aMap.Add(E.Current())) continue;
4183 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
4184 aSubShape = E.Current();
4192 TopoDS_Face aFace = TopoDS::Face(aWhat);
4193 TopExp_Explorer E(aWhere, TopAbs_FACE);
4194 for(; E.More(); E.Next()) {
4195 if(!aMap.Add(E.Current())) continue;
4196 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
4197 aSubShape = E.Current();
4204 case TopAbs_SOLID: {
4205 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
4206 TopExp_Explorer E(aWhere, TopAbs_SOLID);
4207 for(; E.More(); E.Next()) {
4208 if(!aMap.Add(E.Current())) continue;
4209 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
4210 aSubShape = E.Current();
4222 TopTools_IndexedMapOfShape anIndices;
4223 TopExp::MapShapes(aWhere, anIndices);
4224 if (anIndices.Contains(aSubShape))
4225 anIndex = anIndices.FindIndex(aSubShape);
4228 if (anIndex < 0) return NULL;
4230 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
4232 anArray->SetValue(1, anIndex);
4234 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
4235 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
4237 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
4238 << theShapeWhere << ", " << theShapeWhat << ")";