1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : GEOMImpl_IShapesOperations.cxx
22 // Author : modified by Lioka RAZAFINDRAZAKA (CEA) 22/06/2007
26 #include <Standard_Stream.hxx>
28 #include "GEOMImpl_IShapesOperations.hxx"
30 #include "GEOMImpl_Types.hxx"
32 #include "GEOMImpl_VectorDriver.hxx"
33 #include "GEOMImpl_ShapeDriver.hxx"
34 #include "GEOMImpl_CopyDriver.hxx"
35 #include "GEOMImpl_GlueDriver.hxx"
37 #include "GEOMImpl_IVector.hxx"
38 #include "GEOMImpl_IShapes.hxx"
39 #include "GEOMImpl_IGlue.hxx"
41 #include "GEOMImpl_Block6Explorer.hxx"
43 #include "GEOM_Function.hxx"
44 #include "GEOM_ISubShape.hxx"
45 #include "GEOM_PythonDump.hxx"
47 #include "GEOMAlgo_FinderShapeOn1.hxx"
48 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
49 #include "GEOMAlgo_FinderShapeOn2.hxx"
50 #include "GEOMAlgo_ClsfBox.hxx"
51 #include "GEOMAlgo_ClsfSolid.hxx"
52 #include "GEOMAlgo_Gluer1.hxx"
53 #include "GEOMAlgo_ListIteratorOfListOfCoupleOfShapes.hxx"
54 #include "GEOMAlgo_CoupleOfShapes.hxx"
55 #include "GEOMAlgo_ListOfCoupleOfShapes.hxx"
57 #include "utilities.h"
59 #include "Utils_ExceptHandlers.hxx"
61 #include <TFunction_DriverTable.hxx>
62 #include <TFunction_Driver.hxx>
63 #include <TFunction_Logbook.hxx>
64 #include <TDataStd_Integer.hxx>
65 #include <TDataStd_IntegerArray.hxx>
66 #include <TDF_Tool.hxx>
68 #include <BRepExtrema_ExtCF.hxx>
69 #include <BRepExtrema_DistShapeShape.hxx>
71 #include <BRep_Tool.hxx>
72 #include <BRep_Builder.hxx>
73 #include <BRepTools.hxx>
74 #include <BRepGProp.hxx>
75 #include <BRepAdaptor_Curve.hxx>
76 #include <BRepAdaptor_Surface.hxx>
77 #include <BRepBndLib.hxx>
78 #include <BRepBuilderAPI_MakeFace.hxx>
79 #include <BRepMesh_IncrementalMesh.hxx>
84 #include <TopoDS_Shape.hxx>
85 #include <TopoDS_Solid.hxx>
86 #include <TopoDS_Face.hxx>
87 #include <TopoDS_Edge.hxx>
88 #include <TopoDS_Vertex.hxx>
89 #include <TopoDS_Compound.hxx>
90 #include <TopoDS_Iterator.hxx>
91 #include <TopExp_Explorer.hxx>
92 #include <TopLoc_Location.hxx>
93 #include <TopTools_MapOfShape.hxx>
94 #include <TopTools_MapOfOrientedShape.hxx>
95 #include <TopTools_Array1OfShape.hxx>
96 #include <TopTools_ListIteratorOfListOfShape.hxx>
97 #include <TopTools_IndexedMapOfShape.hxx>
99 #include <Geom_Surface.hxx>
100 #include <Geom_Plane.hxx>
101 #include <Geom_SphericalSurface.hxx>
102 #include <Geom_CylindricalSurface.hxx>
103 #include <GeomAdaptor_Surface.hxx>
105 #include <GeomLib_Tool.hxx>
106 #include <Geom2d_Curve.hxx>
108 #include <Bnd_Box.hxx>
109 #include <GProp_GProps.hxx>
110 #include <gp_Pnt.hxx>
111 #include <gp_Lin.hxx>
112 #include <TColStd_ListOfInteger.hxx>
113 #include <TColStd_ListIteratorOfListOfInteger.hxx>
114 #include <TColStd_Array1OfReal.hxx>
115 #include <TColStd_HArray1OfInteger.hxx>
119 #include <Standard_NullObject.hxx>
120 #include <Standard_Failure.hxx>
121 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
123 // Includes added for GetInPlace algorithm improvement
125 #include <GEOMImpl_MeasureDriver.hxx>
126 #include <GEOMImpl_IMeasure.hxx>
127 #include <BRepBuilderAPI_MakeVertex.hxx>
129 #include <BRepClass_FaceClassifier.hxx>
130 #include <BRepClass3d_SolidClassifier.hxx>
131 #include <Precision.hxx>
133 //=============================================================================
137 //=============================================================================
138 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
139 : GEOM_IOperations(theEngine, theDocID)
141 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
144 //=============================================================================
148 //=============================================================================
149 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
151 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
154 //=============================================================================
158 //=============================================================================
159 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
160 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
164 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
166 //Add a new Edge object
167 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
169 //Add a new Vector function
170 Handle(GEOM_Function) aFunction =
171 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
173 //Check if the function is set correctly
174 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
176 GEOMImpl_IVector aPI (aFunction);
178 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
179 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
180 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
182 aPI.SetPoint1(aRef1);
183 aPI.SetPoint2(aRef2);
185 //Compute the Edge value
187 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
190 if (!GetSolver()->ComputeFunction(aFunction)) {
191 SetErrorCode("Vector driver failed");
195 catch (Standard_Failure) {
196 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
197 SetErrorCode(aFail->GetMessageString());
201 //Make a Python command
202 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
203 << thePnt1 << ", " << thePnt2 << ")";
209 //=============================================================================
213 //=============================================================================
214 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
215 (std::list<Handle(GEOM_Object)> theShapes)
217 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
220 //=============================================================================
224 //=============================================================================
225 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
226 const bool isPlanarWanted)
230 if (theWire.IsNull()) return NULL;
232 //Add a new Face object
233 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
235 //Add a new Shape function for creation of a face from a wire
236 Handle(GEOM_Function) aFunction =
237 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
238 if (aFunction.IsNull()) return NULL;
240 //Check if the function is set correctly
241 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
243 GEOMImpl_IShapes aCI (aFunction);
245 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
247 if (aRefWire.IsNull()) return NULL;
249 aCI.SetBase(aRefWire);
250 aCI.SetIsPlanar(isPlanarWanted);
252 //Compute the Face value
254 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
257 if (!GetSolver()->ComputeFunction(aFunction)) {
258 SetErrorCode("Shape driver failed to compute a face");
262 catch (Standard_Failure) {
263 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
264 SetErrorCode(aFail->GetMessageString());
268 //Make a Python command
269 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
270 << theWire << ", " << (int)isPlanarWanted << ")";
276 //=============================================================================
280 //=============================================================================
281 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
282 (std::list<Handle(GEOM_Object)> theShapes,
283 const bool isPlanarWanted)
288 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
291 Handle(GEOM_Function) aFunction =
292 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
293 if (aFunction.IsNull()) return NULL;
295 //Check if the function is set correctly
296 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
298 GEOMImpl_IShapes aCI (aFunction);
300 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
303 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
304 for (; it != theShapes.end(); it++) {
305 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
306 if (aRefSh.IsNull()) {
307 SetErrorCode("NULL argument shape for the face construction");
310 aShapesSeq->Append(aRefSh);
312 aCI.SetShapes(aShapesSeq);
314 aCI.SetIsPlanar(isPlanarWanted);
318 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
321 if (!GetSolver()->ComputeFunction(aFunction)) {
322 SetErrorCode("Shape driver failed");
326 catch (Standard_Failure) {
327 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
328 SetErrorCode(aFail->GetMessageString());
332 //Make a Python command
333 GEOM::TPythonDump pd (aFunction);
334 pd << aShape << " = geompy.MakeFaceWires([";
337 it = theShapes.begin();
338 if (it != theShapes.end()) {
340 while (it != theShapes.end()) {
341 pd << ", " << (*it++);
344 pd << "], " << (int)isPlanarWanted << ")";
350 //=============================================================================
354 //=============================================================================
355 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
356 (std::list<Handle(GEOM_Object)> theShapes)
358 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
361 //=============================================================================
365 //=============================================================================
366 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
367 (std::list<Handle(GEOM_Object)> theShapes)
369 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
372 //=============================================================================
376 //=============================================================================
377 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
381 if (theShell.IsNull()) return NULL;
383 //Add a new Solid object
384 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
386 //Add a new Solid function for creation of a solid from a shell
387 Handle(GEOM_Function) aFunction =
388 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
389 if (aFunction.IsNull()) return NULL;
391 //Check if the function is set correctly
392 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
394 GEOMImpl_IShapes aCI (aFunction);
396 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
398 if (aRefShell.IsNull()) return NULL;
400 aCI.SetBase(aRefShell);
402 //Compute the Solid value
404 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
407 if (!GetSolver()->ComputeFunction(aFunction)) {
408 SetErrorCode("Solid driver failed");
412 catch (Standard_Failure) {
413 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
414 SetErrorCode(aFail->GetMessageString());
418 //Make a Python command
419 GEOM::TPythonDump(aFunction) << aSolid
420 << " = geompy.MakeSolid(" << theShell << ")";
426 //=============================================================================
430 //=============================================================================
431 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
432 (std::list<Handle(GEOM_Object)> theShapes)
434 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
437 //=============================================================================
441 //=============================================================================
442 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
443 (std::list<Handle(GEOM_Object)> theShapes,
444 const Standard_Integer theObjectType,
445 const Standard_Integer theFunctionType,
446 const TCollection_AsciiString& theMethodName)
451 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
454 Handle(GEOM_Function) aFunction =
455 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
456 if (aFunction.IsNull()) return NULL;
458 //Check if the function is set correctly
459 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
461 GEOMImpl_IShapes aCI (aFunction);
463 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
466 std::list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
467 for (; it != theShapes.end(); it++) {
468 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
469 if (aRefSh.IsNull()) {
470 SetErrorCode("NULL argument shape for the shape construction");
473 aShapesSeq->Append(aRefSh);
475 aCI.SetShapes(aShapesSeq);
479 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
482 if (!GetSolver()->ComputeFunction(aFunction)) {
483 SetErrorCode("Shape driver failed");
487 catch (Standard_Failure) {
488 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
489 SetErrorCode(aFail->GetMessageString());
493 //Make a Python command
494 GEOM::TPythonDump pd (aFunction);
495 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
498 it = theShapes.begin();
499 if (it != theShapes.end()) {
501 while (it != theShapes.end()) {
502 pd << ", " << (*it++);
511 //=============================================================================
515 //=============================================================================
516 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
517 (Handle(GEOM_Object) theShape,
518 const Standard_Real theTolerance,
519 const Standard_Boolean doKeepNonSolids)
523 if (theShape.IsNull()) return NULL;
525 //Add a new Glued object
526 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
528 //Add a new Glue function
529 Handle(GEOM_Function) aFunction;
530 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
531 if (aFunction.IsNull()) return NULL;
533 //Check if the function is set correctly
534 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
536 GEOMImpl_IGlue aCI (aFunction);
538 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
539 if (aRefShape.IsNull()) return NULL;
541 aCI.SetBase(aRefShape);
542 aCI.SetTolerance(theTolerance);
543 aCI.SetKeepNonSolids(doKeepNonSolids);
545 //Compute the sub-shape value
546 Standard_Boolean isWarning = Standard_False;
548 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
551 if (!GetSolver()->ComputeFunction(aFunction)) {
552 SetErrorCode("Shape driver failed to glue faces");
556 catch (Standard_Failure) {
557 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
558 SetErrorCode(aFail->GetMessageString());
559 // to provide warning
560 if (!aFunction->GetValue().IsNull()) {
561 isWarning = Standard_True;
567 //Make a Python command
568 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
569 << theShape << ", " << theTolerance << ")";
571 // to provide warning
572 if (!isWarning) SetErrorCode(OK);
576 //=============================================================================
580 //=============================================================================
581 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetGlueFaces
582 (Handle(GEOM_Object) theShape,
583 const Standard_Real theTolerance)
587 if (theShape.IsNull()) return NULL;
588 TopoDS_Shape aShape = theShape->GetValue();
589 if (aShape.IsNull()) return NULL;
591 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
593 Standard_Integer iErr;
595 GEOMAlgo_Gluer1 aGluer;
596 GEOMAlgo_ListIteratorOfListOfCoupleOfShapes aItCS;
597 GEOMAlgo_CoupleOfShapes aCS;
598 GEOMAlgo_ListOfCoupleOfShapes aLCS;
600 //aGluer = new GEOMAlgo_Gluer1;
601 aGluer.SetShape(aShape);
602 aGluer.SetTolerance(theTolerance);
604 iErr = aGluer.ErrorStatus();
605 if (iErr) return NULL;
607 TopTools_ListOfShape listShape;
608 const GEOMAlgo_ListOfCoupleOfShapes& aLCSG = aGluer.GluedFaces();
610 aItCS.Initialize(aLCSG);
611 for (; aItCS.More(); aItCS.Next()) {
612 const GEOMAlgo_CoupleOfShapes& aCSG = aItCS.Value();
613 listShape.Append(aCSG.Shape1());
616 TopTools_ListIteratorOfListOfShape itSub (listShape);
617 TCollection_AsciiString anAsciiList, anEntry;
618 TopTools_IndexedMapOfShape anIndices;
619 TopExp::MapShapes(aShape, anIndices);
620 Handle(TColStd_HArray1OfInteger) anArray;
621 Handle(GEOM_Object) anObj;
622 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
623 TopoDS_Shape aValue = itSub.Value();
624 anArray = new TColStd_HArray1OfInteger(1,1);
625 anArray->SetValue(1, anIndices.FindIndex(aValue));
626 anObj = GetEngine()->AddSubShape(theShape, anArray);
627 if (!anObj.IsNull()) {
630 // for python command
631 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
632 anAsciiList += anEntry;
637 //Make a Python command
638 if(anAsciiList.Length()>0)
639 anAsciiList.Trunc(anAsciiList.Length() - 1);
640 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
641 GEOM::TPythonDump pd (aFunction, /*append=*/true);
642 pd << "[" << anAsciiList.ToCString();
643 pd << "] = geompy.GetGlueFaces(" << theShape << ", " << theTolerance << ")";
650 //=============================================================================
652 * MakeGlueFacesByList
654 //=============================================================================
655 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFacesByList
656 (Handle(GEOM_Object) theShape,
657 const Standard_Real theTolerance,
658 std::list<Handle(GEOM_Object)> theFaces,
659 const Standard_Boolean doKeepNonSolids)
663 if (theShape.IsNull()) return NULL;
665 //Add a new Glued object
666 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
668 //Add a new Glue function
669 Handle(GEOM_Function) aFunction;
670 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES_BY_LIST);
671 if (aFunction.IsNull()) return NULL;
673 //Check if the function is set correctly
674 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
676 GEOMImpl_IGlue aCI (aFunction);
678 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
679 if (aRefShape.IsNull()) return NULL;
681 aCI.SetBase(aRefShape);
682 aCI.SetTolerance(theTolerance);
683 aCI.SetKeepNonSolids(doKeepNonSolids);
685 Handle(TColStd_HSequenceOfTransient) aFaces = new TColStd_HSequenceOfTransient;
686 std::list<Handle(GEOM_Object)>::iterator it = theFaces.begin();
687 for (; it != theFaces.end(); it++) {
688 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
689 if (aRefSh.IsNull()) {
690 SetErrorCode("NULL argument shape for the shape construction");
693 aFaces->Append(aRefSh);
695 aCI.SetFaces(aFaces);
697 //Compute the sub-shape value
698 Standard_Boolean isWarning = Standard_False;
700 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
703 if (!GetSolver()->ComputeFunction(aFunction)) {
704 SetErrorCode("Shape driver failed to glue faces");
708 catch (Standard_Failure) {
709 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
710 SetErrorCode(aFail->GetMessageString());
711 // to provide warning
712 if (!aFunction->GetValue().IsNull()) {
713 isWarning = Standard_True;
719 //Make a Python command
721 GEOM::TPythonDump pd(aFunction);
722 pd << aGlued << " = geompy.MakeGlueFacesByList("
723 << theShape << ", " << theTolerance << ", [";
725 it = theFaces.begin();
726 if (it != theFaces.end()) {
728 while (it != theFaces.end()) {
729 pd << ", " << (*it++);
734 // to provide warning
735 if (!isWarning) SetErrorCode(OK);
739 //=============================================================================
743 //=============================================================================
744 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
745 (Handle(GEOM_Object) theShape,
746 const Standard_Integer theShapeType,
747 const Standard_Boolean isSorted)
751 if (theShape.IsNull()) return NULL;
752 TopoDS_Shape aShape = theShape->GetValue();
753 if (aShape.IsNull()) return NULL;
755 Handle(GEOM_Function) aMainShape = theShape->GetLastFunction();
757 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
758 Handle(GEOM_Object) anObj;
759 TopTools_MapOfShape mapShape;
760 TopTools_ListOfShape listShape;
762 if (aShape.ShapeType() == TopAbs_COMPOUND &&
763 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
764 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
765 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
766 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
767 for (; It.More(); It.Next()) {
768 if (mapShape.Add(It.Value())) {
769 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
770 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
771 listShape.Append(It.Value());
776 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
777 for (; exp.More(); exp.Next())
778 if (mapShape.Add(exp.Current()))
779 listShape.Append(exp.Current());
782 if (listShape.IsEmpty()) {
783 //SetErrorCode("The given shape has no sub-shapes of the requested type");
784 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
789 SortShapes(listShape);
791 TopTools_IndexedMapOfShape anIndices;
792 TopExp::MapShapes(aShape, anIndices);
793 Handle(TColStd_HArray1OfInteger) anArray;
795 TopTools_ListIteratorOfListOfShape itSub (listShape);
796 TCollection_AsciiString anAsciiList, anEntry;
797 for (int index = 1; itSub.More(); itSub.Next(), ++index)
799 TopoDS_Shape aValue = itSub.Value();
800 anArray = new TColStd_HArray1OfInteger(1,1);
801 anArray->SetValue(1, anIndices.FindIndex(aValue));
803 //anObj = GetEngine()->AddSubShape(theShape, anArray);
805 anObj = GetEngine()->AddObject(GetDocID(), GEOM_SUBSHAPE);
806 Handle(GEOM_Function) aFunction = anObj->AddFunction(GEOM_Object::GetSubShapeID(), 1);
807 if (aFunction.IsNull()) return aSeq;
809 GEOM_ISubShape aSSI (aFunction);
810 aSSI.SetMainShape(aMainShape);
811 aSSI.SetIndices(anArray);
813 // Set function value directly, as we know it.
814 // Usage of Solver here would lead to significant loss of time,
815 // because GEOM_SubShapeDriver will build TopTools_IndexedMapOfShape
816 // on the main shape for each being calculated sub-shape separately.
817 aFunction->SetValue(aValue);
820 if (!anObj.IsNull()) {
823 // for python command
824 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
825 anAsciiList += anEntry;
830 //Make a Python command
831 anAsciiList.Trunc(anAsciiList.Length() - 1);
833 GEOM::TPythonDump pd (aMainShape, /*append=*/true);
834 pd << "[" << anAsciiList.ToCString();
835 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
836 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
843 //=============================================================================
847 //=============================================================================
848 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
849 (Handle(GEOM_Object) theShape,
850 const Standard_Integer theShapeType,
851 const Standard_Boolean isSorted)
855 if (theShape.IsNull()) return NULL;
856 TopoDS_Shape aShape = theShape->GetValue();
857 if (aShape.IsNull()) return NULL;
859 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
860 TopTools_MapOfShape mapShape;
861 TopTools_ListOfShape listShape;
863 if (aShape.ShapeType() == TopAbs_COMPOUND &&
864 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
865 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
866 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
867 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
868 for (; It.More(); It.Next()) {
869 if (mapShape.Add(It.Value())) {
870 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
871 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
872 listShape.Append(It.Value());
877 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
878 for (; exp.More(); exp.Next())
879 if (mapShape.Add(exp.Current()))
880 listShape.Append(exp.Current());
883 if (listShape.IsEmpty()) {
884 //SetErrorCode("The given shape has no sub-shapes of the requested type");
885 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
890 SortShapes(listShape);
892 TopTools_IndexedMapOfShape anIndices;
893 TopExp::MapShapes(aShape, anIndices);
894 Handle(TColStd_HArray1OfInteger) anArray;
896 TopTools_ListIteratorOfListOfShape itSub (listShape);
897 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
898 TopoDS_Shape aValue = itSub.Value();
899 aSeq->Append(anIndices.FindIndex(aValue));
902 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
904 //Make a Python command
905 GEOM::TPythonDump pd (aFunction, /*append=*/true);
906 pd << "listSubShapeIDs = geompy.SubShapeAll";
907 pd << (isSorted ? "SortedIDs(" : "IDs(");
908 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
914 //=============================================================================
918 //=============================================================================
919 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
920 (Handle(GEOM_Object) theMainShape,
921 const Standard_Integer theID)
925 if (theMainShape.IsNull()) return NULL;
927 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
928 anArray->SetValue(1, theID);
929 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
930 if (anObj.IsNull()) {
931 SetErrorCode("Can not get a sub-shape with the given ID");
935 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
937 //Make a Python command
938 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
939 << theMainShape << ", [" << theID << "])";
945 //=============================================================================
949 //=============================================================================
950 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
951 Handle(GEOM_Object) theSubShape)
955 TopoDS_Shape aMainShape = theMainShape->GetValue();
956 TopoDS_Shape aSubShape = theSubShape->GetValue();
958 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
960 TopTools_IndexedMapOfShape anIndices;
961 TopExp::MapShapes(aMainShape, anIndices);
962 if (anIndices.Contains(aSubShape)) {
964 return anIndices.FindIndex(aSubShape);
970 //=============================================================================
974 //=============================================================================
975 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
976 Handle(GEOM_Object) theSubShape)
980 TopoDS_Shape aMainShape = theMainShape->GetValue();
981 TopoDS_Shape aSubShape = theSubShape->GetValue();
983 if (aMainShape.IsNull() || aSubShape.IsNull()) {
984 SetErrorCode("Null argument shape given");
989 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
991 TopTools_ListOfShape CL;
992 CL.Append(aMainShape);
993 TopTools_ListIteratorOfListOfShape itC;
994 for (itC.Initialize(CL); itC.More(); itC.Next()) {
995 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
996 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
997 if (it.Value().IsSame(aSubShape))
1001 CL.Append(it.Value());
1006 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
1007 TopTools_MapOfShape M;
1008 for (; anExp.More(); anExp.Next()) {
1009 if (M.Add(anExp.Current())) {
1010 if (anExp.Current().IsSame(aSubShape))
1017 SetErrorCode("The sub-shape does not belong to the main shape");
1021 //=============================================================================
1023 * GetShapeTypeString
1025 //=============================================================================
1026 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
1030 TCollection_AsciiString aTypeName ("Null Shape");
1032 TopoDS_Shape aShape = theShape->GetValue();
1033 if (aShape.IsNull())
1036 switch (aShape.ShapeType() )
1038 case TopAbs_COMPOUND:
1039 aTypeName = "Compound";
1041 case TopAbs_COMPSOLID:
1042 aTypeName = "Compound Solid";
1045 aTypeName = "Solid";
1048 aTypeName = "Shell";
1052 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
1053 if (surf.GetType() == GeomAbs_Plane)
1054 aTypeName = "Plane";
1055 else if (surf.GetType() == GeomAbs_Cylinder)
1056 aTypeName = "Cylindrical Face";
1057 else if (surf.GetType() == GeomAbs_Sphere)
1058 aTypeName = "Spherical Face";
1059 else if (surf.GetType() == GeomAbs_Torus)
1060 aTypeName = "Toroidal Face";
1061 else if (surf.GetType() == GeomAbs_Cone)
1062 aTypeName = "Conical Face";
1064 aTypeName = "GEOM::FACE";
1072 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
1073 if (curv.GetType() == GeomAbs_Line) {
1074 if ((Abs(curv.FirstParameter()) >= 1E6) ||
1075 (Abs(curv.LastParameter()) >= 1E6))
1079 } else if (curv.GetType() == GeomAbs_Circle) {
1080 if (curv.IsClosed())
1081 aTypeName = "Circle";
1090 aTypeName = "Vertex";
1093 aTypeName = "Shape";
1096 aTypeName = "Shape of unknown type";
1102 //=============================================================================
1106 //=============================================================================
1107 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
1111 Standard_Integer nb = 0;
1113 if (theShape.IsNull()) return -1;
1114 TopoDS_Shape aShape = theShape->GetValue();
1115 if (aShape.IsNull()) return -1;
1117 TopTools_MapOfShape mapShape;
1119 TopExp_Explorer exp (aShape, TopAbs_FACE);
1120 for (; exp.More(); exp.Next())
1121 if (mapShape.Add(exp.Current()))
1128 //=============================================================================
1132 //=============================================================================
1133 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
1137 Standard_Integer nb = 0;
1139 if (theShape.IsNull()) return -1;
1140 TopoDS_Shape aShape = theShape->GetValue();
1141 if (aShape.IsNull()) return -1;
1143 TopTools_MapOfShape mapShape;
1145 TopExp_Explorer exp (aShape, TopAbs_EDGE);
1146 for (; exp.More(); exp.Next())
1147 if (mapShape.Add(exp.Current()))
1154 //=============================================================================
1158 //=============================================================================
1159 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
1163 if (theShape.IsNull()) return NULL;
1165 //Add a new reversed object
1166 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
1168 //Add a new Revese function
1169 Handle(GEOM_Function) aFunction;
1170 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
1171 if (aFunction.IsNull()) return NULL;
1173 //Check if the function is set correctly
1174 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
1176 GEOMImpl_IShapes aSI (aFunction);
1178 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1179 if (aRefShape.IsNull()) return NULL;
1181 aSI.SetBase(aRefShape);
1183 //Compute the sub-shape value
1185 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1188 if (!GetSolver()->ComputeFunction(aFunction)) {
1189 SetErrorCode("Shape driver failed to reverse shape");
1193 catch (Standard_Failure) {
1194 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1195 SetErrorCode(aFail->GetMessageString());
1199 //Make a Python command
1200 GEOM::TPythonDump(aFunction) << aReversed
1201 << " = geompy.ChangeOrientation(" << theShape << ")";
1207 //=============================================================================
1211 //=============================================================================
1212 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
1213 (Handle(GEOM_Object) theShape)
1217 if (theShape.IsNull()) return NULL;
1218 TopoDS_Shape aShape = theShape->GetValue();
1219 if (aShape.IsNull()) return NULL;
1221 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1223 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1224 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1225 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1227 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1230 SetErrorCode("The given shape has no faces");
1234 TopTools_IndexedMapOfShape anIndices;
1235 TopExp::MapShapes(aShape, anIndices);
1237 Standard_Integer id;
1238 for (; ind <= nbFaces; ind++) {
1239 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1240 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1245 //The explode doesn't change object so no new function is required.
1246 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1248 //Make a Python command
1249 GEOM::TPythonDump(aFunction, /*append=*/true)
1250 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1256 //=======================================================================
1257 //function : GetSharedShapes
1259 //=======================================================================
1260 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1261 (Handle(GEOM_Object) theShape1,
1262 Handle(GEOM_Object) theShape2,
1263 const Standard_Integer theShapeType)
1267 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1269 TopoDS_Shape aShape1 = theShape1->GetValue();
1270 TopoDS_Shape aShape2 = theShape2->GetValue();
1272 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1274 TopTools_IndexedMapOfShape anIndices;
1275 TopExp::MapShapes(aShape1, anIndices);
1276 Handle(TColStd_HArray1OfInteger) anArray;
1278 TopTools_IndexedMapOfShape mapShape1;
1279 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1281 Handle(GEOM_Object) anObj;
1282 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1283 TCollection_AsciiString anAsciiList, anEntry;
1285 TopTools_MapOfShape mapShape2;
1286 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1287 for (; exp.More(); exp.Next()) {
1288 TopoDS_Shape aSS = exp.Current();
1289 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1290 anArray = new TColStd_HArray1OfInteger(1,1);
1291 anArray->SetValue(1, anIndices.FindIndex(aSS));
1292 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1293 aSeq->Append(anObj);
1295 // for python command
1296 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1297 anAsciiList += anEntry;
1302 if (aSeq->IsEmpty()) {
1303 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1307 //Make a Python command
1308 anAsciiList.Trunc(anAsciiList.Length() - 1);
1310 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1312 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1313 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1314 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1320 //=============================================================================
1324 //=============================================================================
1325 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1326 const GEOMAlgo_State theState)
1329 case GEOMAlgo_ST_IN:
1330 theDump << "geompy.GEOM.ST_IN";
1332 case GEOMAlgo_ST_OUT:
1333 theDump << "geompy.GEOM.ST_OUT";
1335 case GEOMAlgo_ST_ON:
1336 theDump << "geompy.GEOM.ST_ON";
1338 case GEOMAlgo_ST_ONIN:
1339 theDump << "geompy.GEOM.ST_ONIN";
1341 case GEOMAlgo_ST_ONOUT:
1342 theDump << "geompy.GEOM.ST_ONOUT";
1345 theDump << "geompy.GEOM.ST_UNKNOWN";
1351 //=======================================================================
1352 //function : checkTypeShapesOn
1354 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1355 * \param theShapeType - the shape type to check
1356 * \retval bool - result of the check
1358 //=======================================================================
1359 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1361 if (theShapeType != TopAbs_VERTEX &&
1362 theShapeType != TopAbs_EDGE &&
1363 theShapeType != TopAbs_FACE &&
1364 theShapeType != TopAbs_SOLID) {
1365 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1371 //=======================================================================
1372 //function : makePlane
1374 * \brief Creates Geom_Plane
1375 * \param theAx1 - shape object defining plane parameters
1376 * \retval Handle(Geom_Surface) - resulting surface
1378 //=======================================================================
1379 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1381 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1382 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1383 TopoDS_Vertex V1, V2;
1384 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1385 if (V1.IsNull() || V2.IsNull()) {
1386 SetErrorCode("Bad edge given for the plane normal vector");
1389 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1390 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1391 if (aVec.Magnitude() < Precision::Confusion()) {
1392 SetErrorCode("Vector with null magnitude given");
1395 return new Geom_Plane(aLoc, aVec);
1398 //=======================================================================
1399 //function : makeCylinder
1401 * \brief Creates Geom_CylindricalSurface
1402 * \param theAx1 - edge defining cylinder axis
1403 * \param theRadius - cylinder radius
1404 * \retval Handle(Geom_Surface) - resulting surface
1406 //=======================================================================
1407 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1408 const Standard_Real theRadius)
1410 //Axis of the cylinder
1411 if (anAxis.ShapeType() != TopAbs_EDGE) {
1412 SetErrorCode("Not an edge given for the axis");
1415 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1416 TopoDS_Vertex V1, V2;
1417 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1418 if (V1.IsNull() || V2.IsNull()) {
1419 SetErrorCode("Bad edge given for the axis");
1422 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1423 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1424 if (aVec.Magnitude() < Precision::Confusion()) {
1425 SetErrorCode("Vector with null magnitude given");
1429 gp_Ax3 anAx3 (aLoc, aVec);
1430 return new Geom_CylindricalSurface(anAx3, theRadius);
1433 //=======================================================================
1434 //function : getShapesOnBoxIDs
1436 * \brief Find IDs of subshapes complying with given status about surface
1437 * \param theBox - the box to check state of subshapes against
1438 * \param theShape - the shape to explore
1439 * \param theShapeType - type of subshape of theShape
1440 * \param theState - required state
1441 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1443 //=======================================================================
1444 Handle(TColStd_HSequenceOfInteger)
1445 GEOMImpl_IShapesOperations::getShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1446 const Handle(GEOM_Object)& theShape,
1447 const Standard_Integer theShapeType,
1448 GEOMAlgo_State theState)
1450 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1452 TopoDS_Shape aBox = theBox->GetValue();
1453 TopoDS_Shape aShape = theShape->GetValue();
1455 // Check presence of triangulation, build if need
1456 if (!CheckTriangulation(aShape)) {
1457 SetErrorCode("Cannot build triangulation on the shape");
1462 GEOMAlgo_FinderShapeOn2 aFinder;
1463 Standard_Real aTol = 0.0001; // default value
1465 Handle(GEOMAlgo_ClsfBox) aClsfBox = new GEOMAlgo_ClsfBox;
1466 aClsfBox->SetBox(aBox);
1468 aFinder.SetShape(aShape);
1469 aFinder.SetTolerance(aTol);
1470 aFinder.SetClsf(aClsfBox);
1471 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1472 aFinder.SetState(theState);
1475 // Interprete results
1476 Standard_Integer iErr = aFinder.ErrorStatus();
1477 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1479 MESSAGE(" iErr : " << iErr);
1480 TCollection_AsciiString aMsg (" iErr : ");
1481 aMsg += TCollection_AsciiString(iErr);
1485 Standard_Integer iWrn = aFinder.WarningStatus();
1486 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1488 MESSAGE(" *** iWrn : " << iWrn);
1491 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1493 if (listSS.Extent() < 1) {
1494 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1495 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1499 // Fill sequence of object IDs
1500 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1502 TopTools_IndexedMapOfShape anIndices;
1503 TopExp::MapShapes(aShape, anIndices);
1505 TopTools_ListIteratorOfListOfShape itSub (listSS);
1506 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1507 int id = anIndices.FindIndex(itSub.Value());
1508 aSeqOfIDs->Append(id);
1514 //=======================================================================
1515 //function : GetShapesOnBoxIDs
1517 * \brief Find subshapes complying with given status about surface
1518 * \param theBox - the box to check state of subshapes against
1519 * \param theShape - the shape to explore
1520 * \param theShapeType - type of subshape of theShape
1521 * \param theState - required state
1522 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1524 //=======================================================================
1525 Handle(TColStd_HSequenceOfInteger)
1526 GEOMImpl_IShapesOperations::GetShapesOnBoxIDs(const Handle(GEOM_Object)& theBox,
1527 const Handle(GEOM_Object)& theShape,
1528 const Standard_Integer theShapeType,
1529 GEOMAlgo_State theState)
1531 // Find subshapes ids
1532 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1533 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1534 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1537 // The GetShapesOnBox() doesn't change object so no new function is required.
1538 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theBox)->GetLastFunction();
1540 // Make a Python command
1541 GEOM::TPythonDump(aFunction)
1542 << "listShapesOnBoxIDs = geompy.GetShapesOnBoxIDs("
1545 << TopAbs_ShapeEnum(theShapeType) << ", "
1552 //=======================================================================
1553 //function : GetShapesOnBox
1555 * \brief Find subshapes complying with given status about surface
1556 * \param theBox - the box to check state of subshapes against
1557 * \param theShape - the shape to explore
1558 * \param theShapeType - type of subshape of theShape
1559 * \param theState - required state
1560 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1562 //=======================================================================
1563 Handle(TColStd_HSequenceOfTransient)
1564 GEOMImpl_IShapesOperations::GetShapesOnBox(const Handle(GEOM_Object)& theBox,
1565 const Handle(GEOM_Object)& theShape,
1566 const Standard_Integer theShapeType,
1567 GEOMAlgo_State theState)
1569 // Find subshapes ids
1570 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1571 getShapesOnBoxIDs (theBox, theShape, theShapeType, theState);
1572 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1575 // Find objects by indices
1576 TCollection_AsciiString anAsciiList;
1577 Handle(TColStd_HSequenceOfTransient) aSeq;
1578 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1579 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1582 // Make a Python command
1584 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1585 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1587 GEOM::TPythonDump(aFunction)
1588 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnBox("
1591 << TopAbs_ShapeEnum(theShapeType) << ", "
1598 //=======================================================================
1599 //function : getShapesOnShapeIDs
1601 * \brief Find IDs of subshapes complying with given status about surface
1602 * \param theCheckShape - the shape to check state of subshapes against
1603 * \param theShape - the shape to explore
1604 * \param theShapeType - type of subshape of theShape
1605 * \param theState - required state
1606 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1608 //=======================================================================
1609 Handle(TColStd_HSequenceOfInteger)
1610 GEOMImpl_IShapesOperations::getShapesOnShapeIDs
1611 (const Handle(GEOM_Object)& theCheckShape,
1612 const Handle(GEOM_Object)& theShape,
1613 const Standard_Integer theShapeType,
1614 GEOMAlgo_State theState)
1616 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1618 TopoDS_Shape aCheckShape = theCheckShape->GetValue();
1619 TopoDS_Shape aShape = theShape->GetValue();
1620 TopTools_ListOfShape res;
1622 // Check presence of triangulation, build if need
1623 if (!CheckTriangulation(aShape)) {
1624 SetErrorCode("Cannot build triangulation on the shape");
1629 GEOMAlgo_FinderShapeOn2 aFinder;
1630 Standard_Real aTol = 0.0001; // default value
1632 Handle(GEOMAlgo_ClsfSolid) aClsfSolid = new GEOMAlgo_ClsfSolid;
1633 aClsfSolid->SetShape(aCheckShape);
1635 aFinder.SetShape(aShape);
1636 aFinder.SetTolerance(aTol);
1637 aFinder.SetClsf(aClsfSolid);
1638 aFinder.SetShapeType( (TopAbs_ShapeEnum)theShapeType );
1639 aFinder.SetState(theState);
1642 // Interprete results
1643 Standard_Integer iErr = aFinder.ErrorStatus();
1644 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1646 MESSAGE(" iErr : " << iErr);
1647 TCollection_AsciiString aMsg (" iErr : ");
1648 aMsg += TCollection_AsciiString(iErr);
1652 Standard_Integer iWrn = aFinder.WarningStatus();
1653 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1655 MESSAGE(" *** iWrn : " << iWrn);
1658 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1660 if (listSS.Extent() < 1) {
1661 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1662 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1665 // Fill sequence of object IDs
1666 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1668 TopTools_IndexedMapOfShape anIndices;
1669 TopExp::MapShapes(aShape, anIndices);
1671 TopTools_ListIteratorOfListOfShape itSub (listSS);
1672 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1673 int id = anIndices.FindIndex(itSub.Value());
1674 aSeqOfIDs->Append(id);
1680 //=======================================================================
1681 //function : GetShapesOnShapeIDs
1683 * \brief Find subshapes complying with given status about surface
1684 * \param theCheckShape - the shape to check state of subshapes against
1685 * \param theShape - the shape to explore
1686 * \param theShapeType - type of subshape of theShape
1687 * \param theState - required state
1688 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1690 //=======================================================================
1691 Handle(TColStd_HSequenceOfInteger)
1692 GEOMImpl_IShapesOperations::GetShapesOnShapeIDs
1693 (const Handle(GEOM_Object)& theCheckShape,
1694 const Handle(GEOM_Object)& theShape,
1695 const Standard_Integer theShapeType,
1696 GEOMAlgo_State theState)
1698 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1699 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1701 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1704 // The GetShapesOnShape() doesn't change object so no new function is required.
1705 Handle(GEOM_Function) aFunction =
1706 GEOM::GetCreatedLast(theShape,theCheckShape)->GetLastFunction();
1708 // Make a Python command
1709 GEOM::TPythonDump(aFunction)
1710 << "listShapesOnBoxIDs = geompy.GetShapesOnShapeIDs("
1711 << theCheckShape << ", "
1713 << TopAbs_ShapeEnum(theShapeType) << ", "
1720 //=======================================================================
1721 //function : GetShapesOnShape
1723 * \brief Find subshapes complying with given status about surface
1724 * \param theCheckShape - the shape to check state of subshapes against
1725 * \param theShape - the shape to explore
1726 * \param theShapeType - type of subshape of theShape
1727 * \param theState - required state
1728 * \retval Handle(TColStd_HSequenceOfTransient) - found subshapes
1730 //=======================================================================
1731 Handle(TColStd_HSequenceOfTransient)
1732 GEOMImpl_IShapesOperations::GetShapesOnShape
1733 (const Handle(GEOM_Object)& theCheckShape,
1734 const Handle(GEOM_Object)& theShape,
1735 const Standard_Integer theShapeType,
1736 GEOMAlgo_State theState)
1738 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1739 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1740 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1743 // Find objects by indices
1744 TCollection_AsciiString anAsciiList;
1745 Handle(TColStd_HSequenceOfTransient) aSeq;
1746 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1748 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1751 // Make a Python command
1753 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1754 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1756 GEOM::TPythonDump(aFunction)
1757 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnShape("
1758 << theCheckShape << ", "
1760 << TopAbs_ShapeEnum(theShapeType) << ", "
1767 //=======================================================================
1768 //function : GetShapesOnShapeAsCompound
1769 //=======================================================================
1770 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetShapesOnShapeAsCompound
1771 (const Handle(GEOM_Object)& theCheckShape,
1772 const Handle(GEOM_Object)& theShape,
1773 const Standard_Integer theShapeType,
1774 GEOMAlgo_State theState)
1776 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1777 getShapesOnShapeIDs (theCheckShape, theShape, theShapeType, theState);
1779 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1782 // Find objects by indices
1783 TCollection_AsciiString anAsciiList;
1784 Handle(TColStd_HSequenceOfTransient) aSeq;
1785 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1787 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1790 TopoDS_Compound aCompound;
1792 B.MakeCompound(aCompound);
1794 for(; i<=aSeq->Length(); i++) {
1795 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(aSeq->Value(i));
1796 TopoDS_Shape aShape_i = anObj->GetValue();
1797 B.Add(aCompound,aShape_i);
1800 //Add a new result object
1801 Handle(GEOM_Object) aRes = GetEngine()->AddObject(GetDocID(), GEOM_SHAPES_ON_SHAPE);
1802 Handle(GEOM_Function) aFunction =
1803 aRes->AddFunction(GEOMImpl_ShapeDriver::GetID(), SHAPES_ON_SHAPE);
1804 aFunction->SetValue(aCompound);
1806 GEOM::TPythonDump(aFunction)
1807 << aRes << " = geompy.GetShapesOnShapeAsCompound("
1808 << theCheckShape << ", "
1810 << TopAbs_ShapeEnum(theShapeType) << ", "
1818 //=======================================================================
1819 //function : getShapesOnSurfaceIDs
1821 * \brief Find IDs of subshapes complying with given status about surface
1822 * \param theSurface - the surface to check state of subshapes against
1823 * \param theShape - the shape to explore
1824 * \param theShapeType - type of subshape of theShape
1825 * \param theState - required state
1826 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1828 //=======================================================================
1829 Handle(TColStd_HSequenceOfInteger)
1830 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1831 const TopoDS_Shape& theShape,
1832 TopAbs_ShapeEnum theShapeType,
1833 GEOMAlgo_State theState)
1835 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1837 // Check presence of triangulation, build if need
1838 if (!CheckTriangulation(theShape)) {
1839 SetErrorCode("Cannot build triangulation on the shape");
1844 GEOMAlgo_FinderShapeOn1 aFinder;
1845 Standard_Real aTol = 0.0001; // default value
1847 aFinder.SetShape(theShape);
1848 aFinder.SetTolerance(aTol);
1849 aFinder.SetSurface(theSurface);
1850 aFinder.SetShapeType(theShapeType);
1851 aFinder.SetState(theState);
1853 // Sets the minimal number of inner points for the faces that do not have own
1854 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1856 aFinder.SetNbPntsMin(3);
1857 // Sets the maximal number of inner points for edges or faces.
1858 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1859 // the performance. If this value =0, all inner points will be taken into account.
1861 aFinder.SetNbPntsMax(100);
1865 // Interprete results
1866 Standard_Integer iErr = aFinder.ErrorStatus();
1867 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1869 MESSAGE(" iErr : " << iErr);
1870 TCollection_AsciiString aMsg (" iErr : ");
1871 aMsg += TCollection_AsciiString(iErr);
1875 Standard_Integer iWrn = aFinder.WarningStatus();
1876 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1878 MESSAGE(" *** iWrn : " << iWrn);
1881 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1883 if (listSS.Extent() < 1) {
1884 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1885 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
1889 // Fill sequence of object IDs
1890 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1892 TopTools_IndexedMapOfShape anIndices;
1893 TopExp::MapShapes(theShape, anIndices);
1895 TopTools_ListIteratorOfListOfShape itSub (listSS);
1896 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1897 int id = anIndices.FindIndex(itSub.Value());
1898 aSeqOfIDs->Append(id);
1904 //=======================================================================
1905 //function : getObjectsShapesOn
1907 * \brief Find shape objects and their entries by their ids
1908 * \param theShapeIDs - incoming shape ids
1909 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1910 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1912 //=======================================================================
1913 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1914 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1915 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1916 TCollection_AsciiString & theShapeEntries)
1918 Handle(TColStd_HSequenceOfTransient) aSeq;
1920 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1922 aSeq = new TColStd_HSequenceOfTransient;
1923 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1924 TCollection_AsciiString anEntry;
1925 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1927 anArray->SetValue(1, theShapeIDs->Value( i ));
1928 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1929 aSeq->Append( anObj );
1931 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1932 if ( i != 1 ) theShapeEntries += ",";
1933 theShapeEntries += anEntry;
1939 //=======================================================================
1940 //function : getShapesOnSurface
1942 * \brief Find subshapes complying with given status about surface
1943 * \param theSurface - the surface to check state of subshapes against
1944 * \param theShape - the shape to explore
1945 * \param theShapeType - type of subshape of theShape
1946 * \param theState - required state
1947 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1948 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1950 //=======================================================================
1951 Handle(TColStd_HSequenceOfTransient)
1952 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1953 const Handle(GEOM_Object)& theShape,
1954 TopAbs_ShapeEnum theShapeType,
1955 GEOMAlgo_State theState,
1956 TCollection_AsciiString & theShapeEntries)
1958 // Find subshapes ids
1959 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1960 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1961 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1964 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1967 //=============================================================================
1971 //=============================================================================
1972 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1973 (const Handle(GEOM_Object)& theShape,
1974 const Standard_Integer theShapeType,
1975 const Handle(GEOM_Object)& theAx1,
1976 const GEOMAlgo_State theState)
1980 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1982 TopoDS_Shape aShape = theShape->GetValue();
1983 TopoDS_Shape anAx1 = theAx1->GetValue();
1985 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1987 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1988 if ( !checkTypeShapesOn( theShapeType ))
1992 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1993 if ( aPlane.IsNull() )
1997 TCollection_AsciiString anAsciiList;
1998 Handle(TColStd_HSequenceOfTransient) aSeq;
1999 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2000 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2003 // Make a Python command
2005 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2006 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2008 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2009 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
2010 << aShapeType << ", " << theAx1 << ", " << theState << ")";
2016 //=============================================================================
2018 * GetShapesOnPlaneWithLocation
2020 //=============================================================================
2021 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
2022 (const Handle(GEOM_Object)& theShape,
2023 const Standard_Integer theShapeType,
2024 const Handle(GEOM_Object)& theAx1,
2025 const Handle(GEOM_Object)& thePnt,
2026 const GEOMAlgo_State theState)
2030 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2032 TopoDS_Shape aShape = theShape->GetValue();
2033 TopoDS_Shape anAx1 = theAx1->GetValue();
2034 TopoDS_Shape anPnt = thePnt->GetValue();
2036 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2038 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2039 if ( !checkTypeShapesOn( theShapeType ))
2043 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
2044 TopoDS_Vertex V1, V2, V3;
2045 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2046 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2048 if (V1.IsNull() || V2.IsNull()) {
2049 SetErrorCode("Bad edge given for the plane normal vector");
2052 V3 = TopoDS::Vertex(anPnt);
2055 SetErrorCode("Bad vertex given for the plane location");
2058 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2059 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2061 if (aVec.Magnitude() < Precision::Confusion()) {
2062 SetErrorCode("Vector with null magnitude given");
2065 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2067 if ( aPlane.IsNull() )
2071 TCollection_AsciiString anAsciiList;
2072 Handle(TColStd_HSequenceOfTransient) aSeq;
2073 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
2074 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2077 // Make a Python command
2079 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2080 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2082 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2083 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
2084 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
2090 //=============================================================================
2092 * GetShapesOnCylinder
2094 //=============================================================================
2095 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
2096 (const Handle(GEOM_Object)& theShape,
2097 const Standard_Integer theShapeType,
2098 const Handle(GEOM_Object)& theAxis,
2099 const Standard_Real theRadius,
2100 const GEOMAlgo_State theState)
2104 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2106 TopoDS_Shape aShape = theShape->GetValue();
2107 TopoDS_Shape anAxis = theAxis->GetValue();
2109 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2111 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2112 if ( !checkTypeShapesOn( aShapeType ))
2115 // Create a cylinder surface
2116 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2117 if ( aCylinder.IsNull() )
2121 TCollection_AsciiString anAsciiList;
2122 Handle(TColStd_HSequenceOfTransient) aSeq;
2123 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
2124 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2127 // Make a Python command
2129 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2130 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2132 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2133 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
2134 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
2140 //=============================================================================
2144 //=============================================================================
2145 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
2146 (const Handle(GEOM_Object)& theShape,
2147 const Standard_Integer theShapeType,
2148 const Handle(GEOM_Object)& theCenter,
2149 const Standard_Real theRadius,
2150 const GEOMAlgo_State theState)
2154 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2156 TopoDS_Shape aShape = theShape->GetValue();
2157 TopoDS_Shape aCenter = theCenter->GetValue();
2159 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2161 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2162 if ( !checkTypeShapesOn( aShapeType ))
2165 // Center of the sphere
2166 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2167 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2169 gp_Ax3 anAx3 (aLoc, gp::DZ());
2170 Handle(Geom_SphericalSurface) aSphere =
2171 new Geom_SphericalSurface(anAx3, theRadius);
2174 TCollection_AsciiString anAsciiList;
2175 Handle(TColStd_HSequenceOfTransient) aSeq;
2176 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
2177 if ( aSeq.IsNull() || aSeq->Length() == 0 )
2180 // Make a Python command
2182 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2183 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2185 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
2186 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
2187 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
2193 //=============================================================================
2195 * GetShapesOnPlaneIDs
2197 //=============================================================================
2198 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
2199 (const Handle(GEOM_Object)& theShape,
2200 const Standard_Integer theShapeType,
2201 const Handle(GEOM_Object)& theAx1,
2202 const GEOMAlgo_State theState)
2206 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
2208 TopoDS_Shape aShape = theShape->GetValue();
2209 TopoDS_Shape anAx1 = theAx1->GetValue();
2211 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
2213 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2214 if ( !checkTypeShapesOn( aShapeType ))
2218 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
2219 if ( aPlane.IsNull() )
2223 Handle(TColStd_HSequenceOfInteger) aSeq;
2224 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2226 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2227 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2229 // Make a Python command
2230 GEOM::TPythonDump(aFunction, /*append=*/true)
2231 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
2232 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
2238 //=============================================================================
2240 * GetShapesOnPlaneWithLocationIDs
2242 //=============================================================================
2243 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
2244 (const Handle(GEOM_Object)& theShape,
2245 const Standard_Integer theShapeType,
2246 const Handle(GEOM_Object)& theAx1,
2247 const Handle(GEOM_Object)& thePnt,
2248 const GEOMAlgo_State theState)
2252 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
2254 TopoDS_Shape aShape = theShape->GetValue();
2255 TopoDS_Shape anAx1 = theAx1->GetValue();
2256 TopoDS_Shape anPnt = thePnt->GetValue();
2258 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
2260 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2261 if ( !checkTypeShapesOn( aShapeType ))
2265 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
2266 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
2267 TopoDS_Vertex V1, V2, V3;
2268 TopExp::Vertices(anEdge, V1, V2, Standard_True);
2269 if (V1.IsNull() || V2.IsNull()) {
2270 SetErrorCode("Bad edge given for the plane normal vector");
2273 V3 = TopoDS::Vertex(anPnt);
2275 SetErrorCode("Bad vertex given for the plane location");
2278 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
2279 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
2280 if (aVec.Magnitude() < Precision::Confusion()) {
2281 SetErrorCode("Vector with null magnitude given");
2285 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
2286 if ( aPlane.IsNull() )
2290 Handle(TColStd_HSequenceOfInteger) aSeq;
2291 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
2293 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
2294 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
2296 // Make a Python command
2297 GEOM::TPythonDump(aFunction, /*append=*/true)
2298 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
2299 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
2305 //=============================================================================
2307 * GetShapesOnCylinderIDs
2309 //=============================================================================
2310 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
2311 (const Handle(GEOM_Object)& theShape,
2312 const Standard_Integer theShapeType,
2313 const Handle(GEOM_Object)& theAxis,
2314 const Standard_Real theRadius,
2315 const GEOMAlgo_State theState)
2319 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
2321 TopoDS_Shape aShape = theShape->GetValue();
2322 TopoDS_Shape anAxis = theAxis->GetValue();
2324 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
2326 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2327 if ( !checkTypeShapesOn( aShapeType ))
2330 // Create a cylinder surface
2331 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
2332 if ( aCylinder.IsNull() )
2336 Handle(TColStd_HSequenceOfInteger) aSeq;
2337 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
2339 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2340 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
2342 // Make a Python command
2343 GEOM::TPythonDump(aFunction, /*append=*/true)
2344 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2345 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
2346 << theRadius << ", " << theState << ")";
2352 //=============================================================================
2354 * GetShapesOnSphereIDs
2356 //=============================================================================
2357 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
2358 (const Handle(GEOM_Object)& theShape,
2359 const Standard_Integer theShapeType,
2360 const Handle(GEOM_Object)& theCenter,
2361 const Standard_Real theRadius,
2362 const GEOMAlgo_State theState)
2366 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
2368 TopoDS_Shape aShape = theShape->GetValue();
2369 TopoDS_Shape aCenter = theCenter->GetValue();
2371 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
2373 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2374 if ( !checkTypeShapesOn( aShapeType ))
2377 // Center of the sphere
2378 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
2379 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
2381 gp_Ax3 anAx3 (aLoc, gp::DZ());
2382 Handle(Geom_SphericalSurface) aSphere =
2383 new Geom_SphericalSurface(anAx3, theRadius);
2386 Handle(TColStd_HSequenceOfInteger) aSeq;
2387 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
2389 // The GetShapesOnSphere() doesn't change object so no new function is required.
2390 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
2392 // Make a Python command
2393 GEOM::TPythonDump(aFunction, /*append=*/true)
2394 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
2395 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
2396 << theRadius << ", " << theState << ")";
2402 //=======================================================================
2403 //function : getShapesOnQuadrangleIDs
2405 * \brief Find IDs of subshapes complying with given status about quadrangle
2406 * \param theShape - the shape to explore
2407 * \param theShapeType - type of subshape of theShape
2408 * \param theTopLeftPoint - top left quadrangle corner
2409 * \param theTopRigthPoint - top right quadrangle corner
2410 * \param theBottomLeftPoint - bottom left quadrangle corner
2411 * \param theBottomRigthPoint - bottom right quadrangle corner
2412 * \param theState - required state
2413 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2415 //=======================================================================
2416 Handle(TColStd_HSequenceOfInteger)
2417 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2418 const Standard_Integer theShapeType,
2419 const Handle(GEOM_Object)& theTopLeftPoint,
2420 const Handle(GEOM_Object)& theTopRigthPoint,
2421 const Handle(GEOM_Object)& theBottomLeftPoint,
2422 const Handle(GEOM_Object)& theBottomRigthPoint,
2423 const GEOMAlgo_State theState)
2427 if ( theShape.IsNull() ||
2428 theTopLeftPoint.IsNull() ||
2429 theTopRigthPoint.IsNull() ||
2430 theBottomLeftPoint.IsNull() ||
2431 theBottomRigthPoint.IsNull() )
2434 TopoDS_Shape aShape = theShape->GetValue();
2435 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
2436 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
2437 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
2438 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
2440 if (aShape.IsNull() ||
2445 aTL.ShapeType() != TopAbs_VERTEX ||
2446 aTR.ShapeType() != TopAbs_VERTEX ||
2447 aBL.ShapeType() != TopAbs_VERTEX ||
2448 aBR.ShapeType() != TopAbs_VERTEX )
2451 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
2452 if ( !checkTypeShapesOn( aShapeType ))
2455 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
2457 // Check presence of triangulation, build if need
2458 if (!CheckTriangulation(aShape)) {
2459 SetErrorCode("Cannot build triangulation on the shape");
2464 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
2465 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
2466 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
2467 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
2469 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
2470 Standard_Real aTol = 0.0001; // default value
2472 aFinder.SetShape(aShape);
2473 aFinder.SetTolerance(aTol);
2474 //aFinder.SetSurface(theSurface);
2475 aFinder.SetShapeType(aShapeType);
2476 aFinder.SetState(theState);
2478 // Sets the minimal number of inner points for the faces that do not have own
2479 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
2481 aFinder.SetNbPntsMin(3);
2482 // Sets the maximal number of inner points for edges or faces.
2483 // It is usefull for the cases when this number is very big (e.g =2000) to improve
2484 // the performance. If this value =0, all inner points will be taken into account.
2486 aFinder.SetNbPntsMax(100);
2490 // Interprete results
2491 Standard_Integer iErr = aFinder.ErrorStatus();
2492 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
2494 MESSAGE(" iErr : " << iErr);
2495 TCollection_AsciiString aMsg (" iErr : ");
2496 aMsg += TCollection_AsciiString(iErr);
2500 Standard_Integer iWrn = aFinder.WarningStatus();
2501 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
2503 MESSAGE(" *** iWrn : " << iWrn);
2506 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
2508 if (listSS.Extent() < 1) {
2509 //SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
2510 SetErrorCode(NOT_FOUND_ANY); // NPAL18017
2514 // Fill sequence of object IDs
2515 aSeqOfIDs = new TColStd_HSequenceOfInteger;
2517 TopTools_IndexedMapOfShape anIndices;
2518 TopExp::MapShapes(aShape, anIndices);
2520 TopTools_ListIteratorOfListOfShape itSub (listSS);
2521 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
2522 int id = anIndices.FindIndex(itSub.Value());
2523 aSeqOfIDs->Append(id);
2528 //=======================================================================
2529 //function : GetShapesOnQuadrangle
2531 * \brief Find subshapes complying with given status about quadrangle
2532 * \param theShape - the shape to explore
2533 * \param theShapeType - type of subshape of theShape
2534 * \param theTopLeftPoint - top left quadrangle corner
2535 * \param theTopRigthPoint - top right quadrangle corner
2536 * \param theBottomLeftPoint - bottom left quadrangle corner
2537 * \param theBottomRigthPoint - bottom right quadrangle corner
2538 * \param theState - required state
2539 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2541 //=======================================================================
2542 Handle(TColStd_HSequenceOfTransient)
2543 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
2544 const Standard_Integer theShapeType,
2545 const Handle(GEOM_Object)& theTopLeftPoint,
2546 const Handle(GEOM_Object)& theTopRigthPoint,
2547 const Handle(GEOM_Object)& theBottomLeftPoint,
2548 const Handle(GEOM_Object)& theBottomRigthPoint,
2549 const GEOMAlgo_State theState)
2552 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2553 getShapesOnQuadrangleIDs( theShape,
2558 theBottomRigthPoint,
2560 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2563 // Find objects by indices
2564 TCollection_AsciiString anAsciiList;
2565 Handle(TColStd_HSequenceOfTransient) aSeq;
2566 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
2567 if ( aSeq.IsNull() || aSeq->IsEmpty() )
2570 // Make a Python command
2572 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
2573 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
2575 GEOM::TPythonDump(aFunction)
2576 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
2578 << TopAbs_ShapeEnum(theShapeType) << ", "
2579 << theTopLeftPoint << ", "
2580 << theTopRigthPoint << ", "
2581 << theBottomLeftPoint << ", "
2582 << theBottomRigthPoint << ", "
2589 //=======================================================================
2590 //function : GetShapesOnQuadrangleIDs
2592 * \brief Find IDs of subshapes complying with given status about quadrangle
2593 * \param theShape - the shape to explore
2594 * \param theShapeType - type of subshape of theShape
2595 * \param theTopLeftPoint - top left quadrangle corner
2596 * \param theTopRigthPoint - top right quadrangle corner
2597 * \param theBottomLeftPoint - bottom left quadrangle corner
2598 * \param theBottomRigthPoint - bottom right quadrangle corner
2599 * \param theState - required state
2600 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2602 //=======================================================================
2603 Handle(TColStd_HSequenceOfInteger)
2604 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2605 const Standard_Integer theShapeType,
2606 const Handle(GEOM_Object)& theTopLeftPoint,
2607 const Handle(GEOM_Object)& theTopRigthPoint,
2608 const Handle(GEOM_Object)& theBottomLeftPoint,
2609 const Handle(GEOM_Object)& theBottomRigthPoint,
2610 const GEOMAlgo_State theState)
2613 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2614 getShapesOnQuadrangleIDs( theShape,
2619 theBottomRigthPoint,
2621 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2624 // Make a Python command
2626 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2627 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2628 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2629 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2630 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2631 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2633 GEOM::TPythonDump(aFunction, /*append=*/true)
2634 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2636 << TopAbs_ShapeEnum(theShapeType) << ", "
2637 << theTopLeftPoint << ", "
2638 << theTopRigthPoint << ", "
2639 << theBottomLeftPoint << ", "
2640 << theBottomRigthPoint << ", "
2647 //=============================================================================
2651 //=============================================================================
2652 static bool GetInPlaceOfShape (const Handle(GEOM_Function)& theWhereFunction,
2653 const TopTools_IndexedMapOfShape& theWhereIndices,
2654 const TopoDS_Shape& theWhat,
2655 TColStd_ListOfInteger& theModifiedList)
2657 if (theWhereFunction.IsNull() || theWhat.IsNull()) return false;
2659 if (theWhereIndices.Contains(theWhat)) {
2660 // entity was not changed by the operation
2661 Standard_Integer aWhatIndex = theWhereIndices.FindIndex(theWhat);
2662 theModifiedList.Append(aWhatIndex);
2666 // try to find in history
2667 TDF_Label aHistoryLabel = theWhereFunction->GetHistoryEntry(Standard_False);
2669 // search in history for all argument shapes
2670 Standard_Boolean isFound = Standard_False;
2671 Standard_Boolean isGood = Standard_False;
2673 TDF_LabelSequence aLabelSeq;
2674 theWhereFunction->GetDependency(aLabelSeq);
2675 Standard_Integer nbArg = aLabelSeq.Length();
2677 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2679 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2681 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2682 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2684 TopTools_IndexedMapOfShape anArgumentIndices;
2685 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2687 if (anArgumentIndices.Contains(theWhat)) {
2688 isFound = Standard_True;
2689 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(theWhat);
2691 // Find corresponding label in history
2692 TDF_Label anArgumentHistoryLabel =
2693 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2694 if (anArgumentHistoryLabel.IsNull()) {
2695 // Lost History of operation argument. Possibly, all its entities was removed.
2696 isGood = Standard_True;
2699 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2701 if (aWhatHistoryLabel.IsNull()) {
2702 // Removed entity ? Compound ? Compsolid ? Shell ? Wire
2703 isGood = Standard_False;
2705 Handle(TDataStd_IntegerArray) anIntegerArray;
2706 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2707 //Error: Empty modifications history for the sought shape.
2708 isGood = Standard_False;
2711 isGood = Standard_True;
2712 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2713 for (imod = 1; imod <= aModifLen; imod++) {
2714 theModifiedList.Append(anIntegerArray->Array()->Value(imod));
2725 // try compound/compsolid/shell/wire element by element
2726 bool isFoundAny = false;
2727 TopTools_MapOfShape mapShape;
2729 if (theWhat.ShapeType() == TopAbs_COMPOUND ||
2730 theWhat.ShapeType() == TopAbs_COMPSOLID) {
2731 // recursive processing of compound/compsolid
2732 TopoDS_Iterator anIt (theWhat, Standard_True, Standard_True);
2733 for (; anIt.More(); anIt.Next()) {
2734 if (mapShape.Add(anIt.Value())) {
2735 TopoDS_Shape curWhat = anIt.Value();
2736 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2737 if (isFoundAny) isFound = Standard_True;
2741 else if (theWhat.ShapeType() == TopAbs_SHELL) {
2742 // try to replace a shell by its faces images
2743 TopExp_Explorer anExp (theWhat, TopAbs_FACE);
2744 for (; anExp.More(); anExp.Next()) {
2745 if (mapShape.Add(anExp.Current())) {
2746 TopoDS_Shape curWhat = anExp.Current();
2747 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2748 if (isFoundAny) isFound = Standard_True;
2752 else if (theWhat.ShapeType() == TopAbs_WIRE) {
2753 // try to replace a wire by its edges images
2754 TopExp_Explorer anExp (theWhat, TopAbs_EDGE);
2755 for (; anExp.More(); anExp.Next()) {
2756 if (mapShape.Add(anExp.Current())) {
2757 TopoDS_Shape curWhat = anExp.Current();
2758 isFoundAny = GetInPlaceOfShape(theWhereFunction, theWhereIndices, curWhat, theModifiedList);
2759 if (isFoundAny) isFound = Standard_True;
2771 //=============================================================================
2773 * GetShapeProperties
2775 //=============================================================================
2776 void GEOMImpl_IShapesOperations::GetShapeProperties( const TopoDS_Shape aShape, Standard_Real tab[],
2779 GProp_GProps theProps;
2781 TopoDS_Shape aPntShape;
2782 Standard_Real aShapeSize;
2784 if (aShape.ShapeType() == TopAbs_EDGE) BRepGProp::LinearProperties(aShape, theProps);
2785 else if (aShape.ShapeType() == TopAbs_FACE) BRepGProp::SurfaceProperties(aShape, theProps);
2786 else BRepGProp::VolumeProperties(aShape, theProps);
2788 aCenterMass = theProps.CentreOfMass();
2789 aShapeSize = theProps.Mass();
2791 aPntShape = BRepBuilderAPI_MakeVertex(aCenterMass).Shape();
2792 aVertex = BRep_Tool::Pnt( TopoDS::Vertex( aPntShape ) );
2793 tab[0] = aVertex.X();
2794 tab[1] = aVertex.Y();
2795 tab[2] = aVertex.Z();
2796 tab[3] = aShapeSize;
2800 //=============================================================================
2804 //=============================================================================
2805 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace (Handle(GEOM_Object) theShapeWhere,
2806 Handle(GEOM_Object) theShapeWhat)
2810 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2812 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2813 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2814 TopoDS_Shape aPntShape;
2815 TopoDS_Vertex aVertex;
2817 if (aWhere.IsNull() || aWhat.IsNull()) {
2818 SetErrorCode("Error: aWhere and aWhat TopoDS_Shape are Null.");
2822 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2823 if (aWhereFunction.IsNull()) {
2824 SetErrorCode("Error: aWhereFunction is Null.");
2828 TopTools_IndexedMapOfShape aWhereIndices;
2829 TopExp::MapShapes(aWhere, aWhereIndices);
2831 TColStd_ListOfInteger aModifiedList;
2832 Standard_Integer aWhereIndex;
2833 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2834 Handle(GEOM_Object) aResult;
2836 bool isFound = false;
2837 Standard_Integer iType = TopAbs_SOLID;
2838 Standard_Integer compType = TopAbs_SOLID;
2839 Standard_Real aWhat_Mass = 0., aWhere_Mass = 0.;
2840 Standard_Real tab_aWhat[4], tab_aWhere[4];
2841 Standard_Real dl_l = 1e-3;
2842 Standard_Real min_l, Tol_1D, Tol_2D, Tol_3D, Tol_Mass;
2843 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2844 Bnd_Box BoundingBox;
2845 gp_Pnt aPnt, aPnt_aWhat, tab_Pnt[2];
2846 GProp_GProps aProps;
2848 // Find the iType of the aWhat shape
2849 if ( aWhat.ShapeType() == TopAbs_EDGE || aWhat.ShapeType() == TopAbs_WIRE ) iType = TopAbs_EDGE;
2850 else if ( aWhat.ShapeType() == TopAbs_FACE || aWhat.ShapeType() == TopAbs_SHELL ) iType = TopAbs_FACE;
2851 else if ( aWhat.ShapeType() == TopAbs_SOLID || aWhat.ShapeType() == TopAbs_COMPSOLID ) iType = TopAbs_SOLID;
2852 else if ( aWhat.ShapeType() == TopAbs_COMPOUND ) {
2853 // Only the iType of the first shape in the compound is taken into account
2854 TopoDS_Iterator It (aWhat, Standard_True, Standard_True);
2855 compType = It.Value().ShapeType();
2856 if ( compType == TopAbs_EDGE || compType == TopAbs_WIRE ) iType = TopAbs_EDGE;
2857 else if ( compType == TopAbs_FACE || compType == TopAbs_SHELL) iType = TopAbs_FACE;
2858 else if ( compType == TopAbs_SOLID || compType == TopAbs_COMPSOLID) iType = TopAbs_SOLID;
2861 SetErrorCode("Error: An attempt to extract a shape of not supported type.");
2865 TopExp_Explorer Exp_aWhat( aWhat, TopAbs_ShapeEnum( iType ) );
2866 TopExp_Explorer Exp_aWhere( aWhere, TopAbs_ShapeEnum( iType ) );
2867 TopExp_Explorer Exp_Edge( aWhere, TopAbs_EDGE );
2869 // Find the shortest edge in theShapeWhere shape
2870 BRepBndLib::Add(aWhere, BoundingBox);
2871 BoundingBox.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2872 min_l = fabs(aXmax - aXmin);
2873 if( min_l < fabs(aYmax - aYmin) ) min_l = fabs(aYmax - aYmin);
2874 if( min_l < fabs(aZmax - aZmin) ) min_l = fabs(aZmax - aZmin);
2876 for ( Standard_Integer nbEdge = 0; Exp_Edge.More(); Exp_Edge.Next(), nbEdge++ ) {
2877 TopExp_Explorer Exp_Vertex( Exp_Edge.Current(), TopAbs_VERTEX);
2878 for ( Standard_Integer nbVertex = 0; Exp_Vertex.More(); Exp_Vertex.Next(), nbVertex++ ) {
2879 aPnt = BRep_Tool::Pnt( TopoDS::Vertex( Exp_Vertex.Current() ) );
2880 tab_Pnt[nbVertex] = aPnt;
2882 if ( ! tab_Pnt[0].IsEqual(tab_Pnt[1], dl_l) ) {
2883 BRepGProp::LinearProperties(Exp_Edge.Current(), aProps);
2884 if ( aProps.Mass() < min_l ) min_l = aProps.Mass();
2888 // Compute tolerances
2889 Tol_1D = dl_l * min_l;
2890 Tol_2D = dl_l * ( min_l * min_l) * ( 2. + dl_l);
2891 Tol_3D = dl_l * ( min_l * min_l * min_l ) * ( 3. + (3 * dl_l) + (dl_l * dl_l) );
2893 if (Tol_1D < Precision::Confusion()) Tol_1D = Precision::Confusion();
2894 if (Tol_2D < Precision::Confusion()) Tol_2D = Precision::Confusion();
2895 if (Tol_3D < Precision::Confusion()) Tol_3D = Precision::Confusion();
2898 if ( iType == TopAbs_EDGE ) Tol_Mass = Tol_1D;
2899 else if ( iType == TopAbs_FACE ) Tol_Mass = Tol_2D;
2901 // Compute the ShapeWhat Mass
2902 for ( ; Exp_aWhat.More(); Exp_aWhat.Next() ) {
2903 if ( iType == TopAbs_EDGE ) BRepGProp::LinearProperties(Exp_aWhat.Current(), aProps);
2904 else if ( iType == TopAbs_FACE ) BRepGProp::SurfaceProperties(Exp_aWhat.Current(), aProps);
2905 else BRepGProp::VolumeProperties(Exp_aWhat.Current(), aProps);
2906 aWhat_Mass += aProps.Mass();
2909 // Searching for the sub-shapes inside the ShapeWhere shape
2910 TopTools_MapOfShape map_aWhere;
2911 for ( Exp_aWhere.ReInit(); Exp_aWhere.More(); Exp_aWhere.Next() ) {
2912 if (!map_aWhere.Add(Exp_aWhere.Current()))
2913 continue; // skip repeated shape to avoid mass addition
2914 GetShapeProperties( Exp_aWhere.Current(), tab_aWhere, aPnt );
2915 for ( Exp_aWhat.ReInit(); Exp_aWhat.More(); Exp_aWhat.Next() ) {
2916 GetShapeProperties( Exp_aWhat.Current(), tab_aWhat, aPnt_aWhat );
2917 if ( fabs(tab_aWhat[3] - tab_aWhere[3]) <= Tol_Mass && aPnt_aWhat.Distance(aPnt) <= Tol_1D )
2920 if ( (tab_aWhat[3] - tab_aWhere[3]) > Tol_Mass ) {
2921 aPntShape = BRepBuilderAPI_MakeVertex( aPnt ).Shape();
2922 aVertex = TopoDS::Vertex( aPntShape );
2923 BRepExtrema_DistShapeShape aWhereDistance ( aVertex, Exp_aWhere.Current() );
2924 BRepExtrema_DistShapeShape aWhatDistance ( aVertex, Exp_aWhat.Current() );
2925 if ( fabs(aWhereDistance.Value() - aWhatDistance.Value()) <= Tol_1D )
2930 aWhereIndex = aWhereIndices.FindIndex(Exp_aWhere.Current());
2931 aModifiedList.Append(aWhereIndex);
2932 aWhere_Mass += tab_aWhere[3];
2937 if ( fabs( aWhat_Mass - aWhere_Mass ) <= Tol_Mass ) break;
2940 if (aModifiedList.Extent() == 0) { // Not found any Results
2941 SetErrorCode(NOT_FOUND_ANY);
2945 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2946 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2947 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++)
2948 aModifiedArray->SetValue(imod, anIterModif.Value());
2951 aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2952 if (aResult.IsNull()) {
2953 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
2957 if (aModifiedArray->Length() > 1) {
2959 aResult->SetType(GEOM_GROUP);
2961 //Set a sub shape type
2962 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
2963 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
2965 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2966 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2969 //Make a Python command
2970 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2972 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2973 << theShapeWhere << ", " << theShapeWhat << ")";
2979 //=======================================================================
2980 //function : GetInPlaceByHistory
2982 //=======================================================================
2983 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlaceByHistory
2984 (Handle(GEOM_Object) theShapeWhere,
2985 Handle(GEOM_Object) theShapeWhat)
2989 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2991 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2992 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2994 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2996 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2997 if (aWhereFunction.IsNull()) return NULL;
2999 //Fill array of indices
3000 TopTools_IndexedMapOfShape aWhereIndices;
3001 TopExp::MapShapes(aWhere, aWhereIndices);
3004 TColStd_ListOfInteger aModifiedList;
3005 bool isFound = GetInPlaceOfShape(aWhereFunction, aWhereIndices, aWhat, aModifiedList);
3007 if (!isFound || aModifiedList.Extent() < 1) {
3008 SetErrorCode("Error: No history found for the sought shape or its sub-shapes.");
3012 Handle(TColStd_HArray1OfInteger) aModifiedArray =
3013 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
3014 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
3015 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
3016 aModifiedArray->SetValue(imod, anIterModif.Value());
3020 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
3021 if (aResult.IsNull()) {
3022 SetErrorCode("Error in algorithm: result found, but cannot be returned.");
3026 if (aModifiedArray->Length() > 1) {
3028 aResult->SetType(GEOM_GROUP);
3030 //Set a sub shape type
3031 TopoDS_Shape aFirstFound = aWhereIndices.FindKey(aModifiedArray->Value(1));
3032 TopAbs_ShapeEnum aShapeType = aFirstFound.ShapeType();
3034 TDF_Label aFreeLabel = aResult->GetFreeLabel();
3035 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
3038 //Make a Python command
3039 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
3041 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlaceByHistory("
3042 << theShapeWhere << ", " << theShapeWhat << ")";
3048 //=======================================================================
3049 //function : SortShapes
3051 //=======================================================================
3052 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
3054 Standard_Integer MaxShapes = SL.Extent();
3055 TopTools_Array1OfShape aShapes (1,MaxShapes);
3056 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
3057 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
3058 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
3060 // Computing of CentreOfMass
3061 Standard_Integer Index;
3064 TopTools_ListIteratorOfListOfShape it(SL);
3065 for (Index=1; it.More(); Index++)
3067 TopoDS_Shape S = it.Value();
3068 SL.Remove( it ); // == it.Next()
3070 OrderInd.SetValue (Index, Index);
3071 if (S.ShapeType() == TopAbs_VERTEX)
3073 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
3074 Length.SetValue( Index, (Standard_Real) S.Orientation());
3078 BRepGProp::LinearProperties (S, GPr);
3079 GPoint = GPr.CentreOfMass();
3080 Length.SetValue( Index, GPr.Mass() );
3082 MidXYZ.SetValue(Index,
3083 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
3084 //cout << Index << " L: " << Length(Index) << "CG: " << MidXYZ(Index) << endl;
3088 Standard_Integer aTemp;
3089 Standard_Boolean exchange, Sort = Standard_True;
3090 Standard_Real tol = Precision::Confusion();
3093 Sort = Standard_False;
3094 for (Index=1; Index < MaxShapes; Index++)
3096 exchange = Standard_False;
3097 Standard_Real dMidXYZ = MidXYZ(OrderInd(Index)) - MidXYZ(OrderInd(Index+1));
3098 Standard_Real dLength = Length(OrderInd(Index)) - Length(OrderInd(Index+1));
3099 if ( dMidXYZ >= tol ) {
3100 // cout << "MidXYZ: " << MidXYZ(OrderInd(Index))<< " > " <<MidXYZ(OrderInd(Index+1))
3101 // << " d: " << dMidXYZ << endl;
3102 exchange = Standard_True;
3104 else if ( Abs(dMidXYZ) < tol && dLength >= tol ) {
3105 // cout << "Length: " << Length(OrderInd(Index))<< " > " <<Length(OrderInd(Index+1))
3106 // << " d: " << dLength << endl;
3107 exchange = Standard_True;
3109 else if ( Abs(dMidXYZ) < tol && Abs(dLength) < tol &&
3110 aShapes(OrderInd(Index)).ShapeType() <= TopAbs_FACE) {
3112 // equal values possible on shapes such as two halves of a sphere and
3113 // a membrane inside the sphere
3115 BRepBndLib::Add( aShapes( OrderInd(Index) ), box1 );
3116 if ( box1.IsVoid() ) continue;
3117 BRepBndLib::Add( aShapes( OrderInd(Index+1) ), box2 );
3118 Standard_Real dSquareExtent = box1.SquareExtent() - box2.SquareExtent();
3119 if ( dSquareExtent >= tol ) {
3120 // cout << "SquareExtent: " << box1.SquareExtent()<<" > "<<box2.SquareExtent() << endl;
3121 exchange = Standard_True;
3123 else if ( Abs(dSquareExtent) < tol ) {
3124 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax, val1, val2;
3125 box1.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3126 val1 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3127 box2.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3128 val2 = (aXmin+aXmax)*999 + (aYmin+aYmax)*99 + (aZmin+aZmax)*0.9;
3129 //exchange = val1 > val2;
3130 if ((val1 - val2) >= tol) {
3131 exchange = Standard_True;
3133 //cout << "box: " << val1<<" > "<<val2 << endl;
3139 // cout << "exchange " << Index << " & " << Index+1 << endl;
3140 aTemp = OrderInd(Index);
3141 OrderInd(Index) = OrderInd(Index+1);
3142 OrderInd(Index+1) = aTemp;
3143 Sort = Standard_True;
3148 for (Index=1; Index <= MaxShapes; Index++)
3149 SL.Append( aShapes( OrderInd(Index) ));
3152 //=======================================================================
3153 //function : CompsolidToCompound
3155 //=======================================================================
3156 TopoDS_Shape GEOMImpl_IShapesOperations::CompsolidToCompound (const TopoDS_Shape& theCompsolid)
3158 if (theCompsolid.ShapeType() != TopAbs_COMPSOLID) {
3159 return theCompsolid;
3162 TopoDS_Compound aCompound;
3164 B.MakeCompound(aCompound);
3166 TopTools_MapOfShape mapShape;
3167 TopoDS_Iterator It (theCompsolid, Standard_True, Standard_True);
3169 for (; It.More(); It.Next()) {
3170 TopoDS_Shape aShape_i = It.Value();
3171 if (mapShape.Add(aShape_i)) {
3172 B.Add(aCompound, aShape_i);
3179 //=======================================================================
3180 //function : CheckTriangulation
3182 //=======================================================================
3183 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
3185 bool isTriangulation = true;
3187 TopExp_Explorer exp (aShape, TopAbs_FACE);
3190 TopLoc_Location aTopLoc;
3191 Handle(Poly_Triangulation) aTRF;
3192 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
3193 if (aTRF.IsNull()) {
3194 isTriangulation = false;
3197 else // no faces, try edges
3199 TopExp_Explorer expe (aShape, TopAbs_EDGE);
3203 TopLoc_Location aLoc;
3204 Handle(Poly_Polygon3D) aPE = BRep_Tool::Polygon3D(TopoDS::Edge(expe.Current()), aLoc);
3206 isTriangulation = false;
3210 if (!isTriangulation) {
3211 // calculate deflection
3212 Standard_Real aDeviationCoefficient = 0.001;
3215 BRepBndLib::Add(aShape, B);
3216 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
3217 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
3219 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
3220 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
3221 Standard_Real aHLRAngle = 0.349066;
3223 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);
3229 #define MAX_TOLERANCE 1.e-7
3231 //=======================================================================
3232 //function : isSameEdge
3233 //purpose : Returns True if two edges coincide
3234 //=======================================================================
3235 static bool isSameEdge(const TopoDS_Edge& theEdge1, const TopoDS_Edge& theEdge2)
3237 TopoDS_Vertex V11, V12, V21, V22;
3238 TopExp::Vertices(theEdge1, V11, V12);
3239 TopExp::Vertices(theEdge2, V21, V22);
3240 gp_Pnt P11 = BRep_Tool::Pnt(V11);
3241 gp_Pnt P12 = BRep_Tool::Pnt(V12);
3242 gp_Pnt P21 = BRep_Tool::Pnt(V21);
3243 gp_Pnt P22 = BRep_Tool::Pnt(V22);
3244 bool coincide = false;
3246 //Check that ends of edges coincide
3247 if(P11.Distance(P21) <= MAX_TOLERANCE) {
3248 if(P12.Distance(P22) <= MAX_TOLERANCE) coincide = true;
3250 else if(P11.Distance(P22) <= MAX_TOLERANCE) {
3251 if(P12.Distance(P21) <= MAX_TOLERANCE) coincide = true;
3254 if(!coincide) return false;
3256 if (BRep_Tool::Degenerated(theEdge1))
3257 if (BRep_Tool::Degenerated(theEdge2)) return true;
3260 if (BRep_Tool::Degenerated(theEdge2)) return false;
3262 double U11, U12, U21, U22;
3263 Handle(Geom_Curve) C1 = BRep_Tool::Curve(theEdge1, U11, U12);
3264 Handle(Geom_Curve) C2 = BRep_Tool::Curve(theEdge2, U21, U22);
3265 if(C1->DynamicType() == C2->DynamicType()) return true;
3267 //Check that both edges has the same geometry
3268 double range = U12-U11;
3269 double U = U11+ range/3.0;
3270 gp_Pnt P1 = C1->Value(U); //Compute a point on one third of the edge's length
3271 U = U11+range*2.0/3.0;
3272 gp_Pnt P2 = C1->Value(U); //Compute a point on two thirds of the edge's length
3274 if(!GeomLib_Tool::Parameter(C2, P1, MAX_TOLERANCE, U) || U < U21 || U > U22)
3277 if(P1.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3279 if(!GeomLib_Tool::Parameter(C2, P2, MAX_TOLERANCE, U) || U < U21 || U > U22)
3282 if(P2.Distance(C2->Value(U)) > MAX_TOLERANCE) return false;
3287 #include <TopoDS_TShape.hxx>
3288 //=======================================================================
3289 //function : isSameFace
3290 //purpose : Returns True if two faces coincide
3291 //=======================================================================
3292 static bool isSameFace(const TopoDS_Face& theFace1, const TopoDS_Face& theFace2)
3294 TopExp_Explorer E(theFace1, TopAbs_EDGE);
3295 TopTools_ListOfShape LS1, LS2;
3296 for(; E.More(); E.Next()) LS1.Append(E.Current());
3298 E.Init(theFace2, TopAbs_EDGE);
3299 for(; E.More(); E.Next()) LS2.Append(E.Current());
3301 //Compare the number of edges in the faces
3302 if(LS1.Extent() != LS2.Extent()) return false;
3304 double aMin = RealFirst(), aMax = RealLast();
3305 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3306 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3308 for(E.Init(theFace1, TopAbs_VERTEX); E.More(); E.Next()) {
3309 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3310 if(P.X() < xminB1) xminB1 = P.X();
3311 if(P.Y() < yminB1) yminB1 = P.Y();
3312 if(P.Z() < zminB1) zminB1 = P.Z();
3313 if(P.X() > xmaxB1) xmaxB1 = P.X();
3314 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3315 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3318 for(E.Init(theFace2, TopAbs_VERTEX); E.More(); E.Next()) {
3319 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3320 if(P.X() < xminB2) xminB2 = P.X();
3321 if(P.Y() < yminB2) yminB2 = P.Y();
3322 if(P.Z() < zminB2) zminB2 = P.Z();
3323 if(P.X() > xmaxB2) xmaxB2 = P.X();
3324 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3325 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3328 //Compare the bounding boxes of both faces
3329 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3332 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3335 Handle(Geom_Surface) S1 = BRep_Tool::Surface(theFace1);
3336 Handle(Geom_Surface) S2 = BRep_Tool::Surface(theFace2);
3338 //Check if there a coincidence of two surfaces at least in two points
3339 double U11, U12, V11, V12, U21, U22, V21, V22;
3340 BRepTools::UVBounds(theFace1, U11, U12, V11, V12);
3341 BRepTools::UVBounds(theFace2, U21, U22, V21, V22);
3343 double rangeU = U12-U11;
3344 double rangeV = V12-V11;
3345 double U = U11 + rangeU/3.0;
3346 double V = V11 + rangeV/3.0;
3347 gp_Pnt P1 = S1->Value(U, V);
3348 U = U11+rangeU*2.0/3.0;
3349 V = V11+rangeV*2.0/3.0;
3350 gp_Pnt P2 = S1->Value(U, V);
3352 if (!GeomLib_Tool::Parameters(S2, P1, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3355 if (P1.Distance(S2->Value(U,V)) > MAX_TOLERANCE) return false;
3357 if (!GeomLib_Tool::Parameters(S2, P2, MAX_TOLERANCE, U, V) || U < U21 || U > U22 || V < V21 || V > V22)
3360 if (P2.Distance(S2->Value(U, V)) > MAX_TOLERANCE) return false;
3362 //Check that each edge of the Face1 has a counterpart in the Face2
3363 TopTools_MapOfOrientedShape aMap;
3364 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3365 for(; LSI1.More(); LSI1.Next()) {
3366 TopoDS_Edge E = TopoDS::Edge(LSI1.Value());
3367 bool isFound = false;
3368 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3369 for(; LSI2.More(); LSI2.Next()) {
3370 TopoDS_Shape aValue = LSI2.Value();
3371 if(aMap.Contains(aValue)) continue; //To avoid checking already found edge several times
3372 if(isSameEdge(E, TopoDS::Edge(aValue))) {
3378 if(!isFound) return false;
3384 //=======================================================================
3385 //function : isSameSolid
3386 //purpose : Returns True if two solids coincide
3387 //=======================================================================
3388 bool isSameSolid(const TopoDS_Solid& theSolid1, const TopoDS_Solid& theSolid2)
3390 TopExp_Explorer E(theSolid1, TopAbs_FACE);
3391 TopTools_ListOfShape LS1, LS2;
3392 for(; E.More(); E.Next()) LS1.Append(E.Current());
3393 E.Init(theSolid2, TopAbs_FACE);
3394 for(; E.More(); E.Next()) LS2.Append(E.Current());
3396 if(LS1.Extent() != LS2.Extent()) return false;
3398 double aMin = RealFirst(), aMax = RealLast();
3399 double xminB1=aMax, yminB1=aMax, zminB1=aMax, xminB2=aMax, yminB2=aMax, zminB2=aMax;
3400 double xmaxB1=aMin, ymaxB1=aMin, zmaxB1=aMin, xmaxB2=aMin, ymaxB2=aMin, zmaxB2=aMin;
3402 for(E.Init(theSolid1, TopAbs_VERTEX); E.More(); E.Next()) {
3403 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3404 if(P.X() < xminB1) xminB1 = P.X();
3405 if(P.Y() < yminB1) yminB1 = P.Y();
3406 if(P.Z() < zminB1) zminB1 = P.Z();
3407 if(P.X() > xmaxB1) xmaxB1 = P.X();
3408 if(P.Y() > ymaxB1) ymaxB1 = P.Y();
3409 if(P.Z() > zmaxB1) zmaxB1 = P.Z();
3412 for(E.Init(theSolid2, TopAbs_VERTEX); E.More(); E.Next()) {
3413 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3414 if(P.X() < xminB2) xminB2 = P.X();
3415 if(P.Y() < yminB2) yminB2 = P.Y();
3416 if(P.Z() < zminB2) zminB2 = P.Z();
3417 if(P.X() > xmaxB2) xmaxB2 = P.X();
3418 if(P.Y() > ymaxB2) ymaxB2 = P.Y();
3419 if(P.Z() > zmaxB2) zmaxB2 = P.Z();
3422 //Compare the bounding boxes of both solids
3423 if(gp_Pnt(xminB1, yminB1, zminB1).Distance(gp_Pnt(xminB2, yminB2, zminB2)) > MAX_TOLERANCE)
3426 if(gp_Pnt(xmaxB1, ymaxB1, zmaxB1).Distance(gp_Pnt(xmaxB2, ymaxB2, zmaxB2)) > MAX_TOLERANCE)
3429 //Check that each face of the Solid1 has a counterpart in the Solid2
3430 TopTools_MapOfOrientedShape aMap;
3431 TopTools_ListIteratorOfListOfShape LSI1(LS1);
3432 for(; LSI1.More(); LSI1.Next()) {
3433 TopoDS_Face F = TopoDS::Face(LSI1.Value());
3434 bool isFound = false;
3435 TopTools_ListIteratorOfListOfShape LSI2(LS2);
3436 for(; LSI2.More(); LSI2.Next()) {
3437 if(aMap.Contains(LSI2.Value())) continue; //To avoid checking already found faces several times
3438 if(isSameFace(F, TopoDS::Face(LSI2.Value()))) {
3439 aMap.Add(LSI2.Value());
3444 if(!isFound) return false;
3450 //=======================================================================
3451 //function : GetSame
3453 //=======================================================================
3454 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSame(const Handle(GEOM_Object)& theShapeWhere,
3455 const Handle(GEOM_Object)& theShapeWhat)
3458 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
3460 TopoDS_Shape aWhere = theShapeWhere->GetValue();
3461 TopoDS_Shape aWhat = theShapeWhat->GetValue();
3463 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
3466 bool isFound = false;
3467 TopoDS_Shape aSubShape;
3468 TopTools_MapOfShape aMap;
3470 switch(aWhat.ShapeType()) {
3471 case TopAbs_VERTEX: {
3472 gp_Pnt P = BRep_Tool::Pnt(TopoDS::Vertex(aWhat));
3473 TopExp_Explorer E(aWhere, TopAbs_VERTEX);
3474 for(; E.More(); E.Next()) {
3475 if(!aMap.Add(E.Current())) continue;
3476 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(E.Current()));
3477 if(P.Distance(P2) <= MAX_TOLERANCE) {
3479 aSubShape = E.Current();
3486 TopoDS_Face aFace = TopoDS::Face(aWhat);
3487 TopExp_Explorer E(aWhere, TopAbs_FACE);
3488 for(; E.More(); E.Next()) {
3489 if(!aMap.Add(E.Current())) continue;
3490 if(isSameFace(aFace, TopoDS::Face(E.Current()))) {
3491 aSubShape = E.Current();
3499 TopoDS_Edge anEdge = TopoDS::Edge(aWhat);
3500 TopExp_Explorer E(aWhere, TopAbs_EDGE);
3501 for(; E.More(); E.Next()) {
3502 if(!aMap.Add(E.Current())) continue;
3503 if(isSameEdge(anEdge, TopoDS::Edge(E.Current()))) {
3504 aSubShape = E.Current();
3511 case TopAbs_SOLID: {
3512 TopoDS_Solid aSolid = TopoDS::Solid(aWhat);
3513 TopExp_Explorer E(aWhere, TopAbs_SOLID);
3514 for(; E.More(); E.Next()) {
3515 if(!aMap.Add(E.Current())) continue;
3516 if(isSameSolid(aSolid, TopoDS::Solid(E.Current()))) {
3517 aSubShape = E.Current();
3529 TopTools_IndexedMapOfShape anIndices;
3530 TopExp::MapShapes(aWhere, anIndices);
3531 if (anIndices.Contains(aSubShape))
3532 anIndex = anIndices.FindIndex(aSubShape);
3535 if(anIndex < 0) return NULL;
3537 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
3539 anArray->SetValue(1, anIndex);
3541 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, anArray);
3542 Handle(GEOM_Function) aFunction = aResult->GetLastFunction();
3544 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetSame("
3545 << theShapeWhere << ", " << theShapeWhat << ")";