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 #include <Standard_Stream.hxx>
22 #include "GEOMImpl_IShapesOperations.hxx"
24 #include "GEOMImpl_Types.hxx"
26 #include "GEOMImpl_VectorDriver.hxx"
27 #include "GEOMImpl_ShapeDriver.hxx"
28 #include "GEOMImpl_CopyDriver.hxx"
29 #include "GEOMImpl_GlueDriver.hxx"
31 #include "GEOMImpl_IVector.hxx"
32 #include "GEOMImpl_IShapes.hxx"
33 #include "GEOMImpl_IGlue.hxx"
35 #include "GEOMImpl_Block6Explorer.hxx"
37 #include "GEOM_Function.hxx"
38 #include "GEOM_PythonDump.hxx"
40 #include "GEOMAlgo_FinderShapeOn1.hxx"
41 #include "GEOMAlgo_FinderShapeOnQuad.hxx"
43 #include "utilities.h"
45 #include "Utils_ExceptHandlers.hxx"
47 #include <TFunction_DriverTable.hxx>
48 #include <TFunction_Driver.hxx>
49 #include <TFunction_Logbook.hxx>
50 #include <TDataStd_Integer.hxx>
51 #include <TDataStd_IntegerArray.hxx>
52 #include <TDF_Tool.hxx>
54 #include <BRepExtrema_ExtCF.hxx>
56 #include <BRep_Tool.hxx>
57 #include <BRepGProp.hxx>
58 #include <BRepAdaptor_Curve.hxx>
59 #include <BRepAdaptor_Surface.hxx>
60 #include <BRepBndLib.hxx>
61 #include <BRepBuilderAPI_MakeFace.hxx>
62 #include <BRepMesh_IncrementalMesh.hxx>
67 #include <TopoDS_Shape.hxx>
68 #include <TopoDS_Face.hxx>
69 #include <TopoDS_Edge.hxx>
70 #include <TopoDS_Vertex.hxx>
71 #include <TopoDS_Iterator.hxx>
72 #include <TopExp_Explorer.hxx>
73 #include <TopLoc_Location.hxx>
74 #include <TopTools_MapOfShape.hxx>
75 #include <TopTools_Array1OfShape.hxx>
76 #include <TopTools_ListIteratorOfListOfShape.hxx>
77 #include <TopTools_IndexedMapOfShape.hxx>
79 #include <Geom_Surface.hxx>
80 #include <Geom_Plane.hxx>
81 #include <Geom_SphericalSurface.hxx>
82 #include <Geom_CylindricalSurface.hxx>
83 #include <GeomAdaptor_Surface.hxx>
85 #include <Geom2d_Curve.hxx>
87 #include <Bnd_Box.hxx>
88 #include <GProp_GProps.hxx>
91 #include <TColStd_ListOfInteger.hxx>
92 #include <TColStd_ListIteratorOfListOfInteger.hxx>
93 #include <TColStd_Array1OfReal.hxx>
94 #include <TColStd_HArray1OfInteger.hxx>
98 #include <Standard_Failure.hxx>
99 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
101 //=============================================================================
105 //=============================================================================
106 GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations (GEOM_Engine* theEngine, int theDocID)
107 : GEOM_IOperations(theEngine, theDocID)
109 MESSAGE("GEOMImpl_IShapesOperations::GEOMImpl_IShapesOperations");
112 //=============================================================================
116 //=============================================================================
117 GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations()
119 MESSAGE("GEOMImpl_IShapesOperations::~GEOMImpl_IShapesOperations");
123 //=============================================================================
127 //=============================================================================
128 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeEdge
129 (Handle(GEOM_Object) thePnt1, Handle(GEOM_Object) thePnt2)
133 if (thePnt1.IsNull() || thePnt2.IsNull()) return NULL;
135 //Add a new Edge object
136 Handle(GEOM_Object) anEdge = GetEngine()->AddObject(GetDocID(), GEOM_EDGE);
138 //Add a new Vector function
139 Handle(GEOM_Function) aFunction =
140 anEdge->AddFunction(GEOMImpl_VectorDriver::GetID(), VECTOR_TWO_PNT);
142 //Check if the function is set correctly
143 if (aFunction->GetDriverGUID() != GEOMImpl_VectorDriver::GetID()) return NULL;
145 GEOMImpl_IVector aPI (aFunction);
147 Handle(GEOM_Function) aRef1 = thePnt1->GetLastFunction();
148 Handle(GEOM_Function) aRef2 = thePnt2->GetLastFunction();
149 if (aRef1.IsNull() || aRef2.IsNull()) return NULL;
151 aPI.SetPoint1(aRef1);
152 aPI.SetPoint2(aRef2);
154 //Compute the Edge value
156 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
159 if (!GetSolver()->ComputeFunction(aFunction)) {
160 SetErrorCode("Vector driver failed");
164 catch (Standard_Failure) {
165 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
166 SetErrorCode(aFail->GetMessageString());
170 //Make a Python command
171 GEOM::TPythonDump(aFunction) << anEdge << " = geompy.MakeEdge("
172 << thePnt1 << ", " << thePnt2 << ")";
178 //=============================================================================
182 //=============================================================================
183 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeWire
184 (list<Handle(GEOM_Object)> theShapes)
186 return MakeShape(theShapes, GEOM_WIRE, WIRE_EDGES, "MakeWire");
189 //=============================================================================
193 //=============================================================================
194 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFace (Handle(GEOM_Object) theWire,
195 const bool isPlanarWanted)
199 if (theWire.IsNull()) return NULL;
201 //Add a new Face object
202 Handle(GEOM_Object) aFace = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
204 //Add a new Shape function for creation of a face from a wire
205 Handle(GEOM_Function) aFunction =
206 aFace->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRE);
207 if (aFunction.IsNull()) return NULL;
209 //Check if the function is set correctly
210 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
212 GEOMImpl_IShapes aCI (aFunction);
214 Handle(GEOM_Function) aRefWire = theWire->GetLastFunction();
216 if (aRefWire.IsNull()) return NULL;
218 aCI.SetBase(aRefWire);
219 aCI.SetIsPlanar(isPlanarWanted);
221 //Compute the Face value
223 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
226 if (!GetSolver()->ComputeFunction(aFunction)) {
227 SetErrorCode("Shape driver failed to compute a face");
231 catch (Standard_Failure) {
232 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
233 SetErrorCode(aFail->GetMessageString());
237 //Make a Python command
238 GEOM::TPythonDump(aFunction) << aFace << " = geompy.MakeFace("
239 << theWire << ", " << (int)isPlanarWanted << ")";
245 //=============================================================================
249 //=============================================================================
250 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeFaceWires
251 (list<Handle(GEOM_Object)> theShapes,
252 const bool isPlanarWanted)
257 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_FACE);
260 Handle(GEOM_Function) aFunction =
261 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), FACE_WIRES);
262 if (aFunction.IsNull()) return NULL;
264 //Check if the function is set correctly
265 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
267 GEOMImpl_IShapes aCI (aFunction);
269 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
272 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
273 for (; it != theShapes.end(); it++) {
274 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
275 if (aRefSh.IsNull()) {
276 SetErrorCode("NULL argument shape for the face construction");
279 aShapesSeq->Append(aRefSh);
281 aCI.SetShapes(aShapesSeq);
283 aCI.SetIsPlanar(isPlanarWanted);
287 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
290 if (!GetSolver()->ComputeFunction(aFunction)) {
291 SetErrorCode("Shape driver failed");
295 catch (Standard_Failure) {
296 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
297 SetErrorCode(aFail->GetMessageString());
301 //Make a Python command
302 GEOM::TPythonDump pd (aFunction);
303 pd << aShape << " = geompy.MakeFaceWires([";
306 it = theShapes.begin();
307 if (it != theShapes.end()) {
309 while (it != theShapes.end()) {
310 pd << ", " << (*it++);
313 pd << "], " << (int)isPlanarWanted << ")";
319 //=============================================================================
323 //=============================================================================
324 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShell
325 (list<Handle(GEOM_Object)> theShapes)
327 return MakeShape(theShapes, GEOM_SHELL, SHELL_FACES, "MakeShell");
330 //=============================================================================
334 //=============================================================================
335 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShells
336 (list<Handle(GEOM_Object)> theShapes)
338 return MakeShape(theShapes, GEOM_SOLID, SOLID_SHELLS, "MakeSolid");
341 //=============================================================================
345 //=============================================================================
346 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeSolidShell (Handle(GEOM_Object) theShell)
350 if (theShell.IsNull()) return NULL;
352 //Add a new Solid object
353 Handle(GEOM_Object) aSolid = GetEngine()->AddObject(GetDocID(), GEOM_SOLID);
355 //Add a new Solid function for creation of a solid from a shell
356 Handle(GEOM_Function) aFunction =
357 aSolid->AddFunction(GEOMImpl_ShapeDriver::GetID(), SOLID_SHELL);
358 if (aFunction.IsNull()) return NULL;
360 //Check if the function is set correctly
361 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
363 GEOMImpl_IShapes aCI (aFunction);
365 Handle(GEOM_Function) aRefShell = theShell->GetLastFunction();
367 if (aRefShell.IsNull()) return NULL;
369 aCI.SetBase(aRefShell);
371 //Compute the Solid value
373 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
376 if (!GetSolver()->ComputeFunction(aFunction)) {
377 SetErrorCode("Solid driver failed");
381 catch (Standard_Failure) {
382 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
383 SetErrorCode(aFail->GetMessageString());
387 //Make a Python command
388 GEOM::TPythonDump(aFunction) << aSolid
389 << " = geompy.MakeSolid(" << theShell << ")";
395 //=============================================================================
399 //=============================================================================
400 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeCompound
401 (list<Handle(GEOM_Object)> theShapes)
403 return MakeShape(theShapes, GEOM_COMPOUND, COMPOUND_SHAPES, "MakeCompound");
406 //=============================================================================
410 //=============================================================================
411 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeShape
412 (list<Handle(GEOM_Object)> theShapes,
413 const Standard_Integer theObjectType,
414 const Standard_Integer theFunctionType,
415 const TCollection_AsciiString& theMethodName)
420 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), theObjectType);
423 Handle(GEOM_Function) aFunction =
424 aShape->AddFunction(GEOMImpl_ShapeDriver::GetID(), theFunctionType);
425 if (aFunction.IsNull()) return NULL;
427 //Check if the function is set correctly
428 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
430 GEOMImpl_IShapes aCI (aFunction);
432 Handle(TColStd_HSequenceOfTransient) aShapesSeq = new TColStd_HSequenceOfTransient;
435 list<Handle(GEOM_Object)>::iterator it = theShapes.begin();
436 for (; it != theShapes.end(); it++) {
437 Handle(GEOM_Function) aRefSh = (*it)->GetLastFunction();
438 if (aRefSh.IsNull()) {
439 SetErrorCode("NULL argument shape for the shape construction");
442 aShapesSeq->Append(aRefSh);
444 aCI.SetShapes(aShapesSeq);
448 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
451 if (!GetSolver()->ComputeFunction(aFunction)) {
452 SetErrorCode("Shape driver failed");
456 catch (Standard_Failure) {
457 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
458 SetErrorCode(aFail->GetMessageString());
462 //Make a Python command
463 GEOM::TPythonDump pd (aFunction);
464 pd << aShape << " = geompy." << theMethodName.ToCString() << "([";
467 it = theShapes.begin();
468 if (it != theShapes.end()) {
470 while (it != theShapes.end()) {
471 pd << ", " << (*it++);
480 //=============================================================================
484 //=============================================================================
485 Handle(GEOM_Object) GEOMImpl_IShapesOperations::MakeGlueFaces
486 (Handle(GEOM_Object) theShape,
487 const Standard_Real theTolerance)
491 if (theShape.IsNull()) return NULL;
493 //Add a new Glued object
494 Handle(GEOM_Object) aGlued = GetEngine()->AddObject(GetDocID(), GEOM_GLUED);
496 //Add a new Glue function
497 Handle(GEOM_Function) aFunction;
498 aFunction = aGlued->AddFunction(GEOMImpl_GlueDriver::GetID(), GLUE_FACES);
499 if (aFunction.IsNull()) return NULL;
501 //Check if the function is set correctly
502 if (aFunction->GetDriverGUID() != GEOMImpl_GlueDriver::GetID()) return NULL;
504 GEOMImpl_IGlue aCI (aFunction);
506 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
507 if (aRefShape.IsNull()) return NULL;
509 aCI.SetBase(aRefShape);
510 aCI.SetTolerance(theTolerance);
512 //Compute the sub-shape value
513 Standard_Boolean isWarning = Standard_False;
515 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
518 if (!GetSolver()->ComputeFunction(aFunction)) {
519 SetErrorCode("Shape driver failed to glue faces");
523 catch (Standard_Failure) {
524 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
525 SetErrorCode(aFail->GetMessageString());
526 // to provide warning
527 if (!aFunction->GetValue().IsNull()) {
528 isWarning = Standard_True;
534 //Make a Python command
535 GEOM::TPythonDump(aFunction) << aGlued << " = geompy.MakeGlueFaces("
536 << theShape << ", " << theTolerance << ")";
538 // to provide warning
539 if (!isWarning) SetErrorCode(OK);
543 //=============================================================================
547 //=============================================================================
548 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::MakeExplode
549 (Handle(GEOM_Object) theShape,
550 const Standard_Integer theShapeType,
551 const Standard_Boolean isSorted)
555 if (theShape.IsNull()) return NULL;
556 TopoDS_Shape aShape = theShape->GetValue();
557 if (aShape.IsNull()) return NULL;
559 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
560 Handle(GEOM_Object) anObj;
561 Handle(GEOM_Function) aFunction;
562 TopTools_MapOfShape mapShape;
563 TopTools_ListOfShape listShape;
565 if (aShape.ShapeType() == TopAbs_COMPOUND &&
566 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
567 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
568 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
569 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
570 for (; It.More(); It.Next()) {
571 if (mapShape.Add(It.Value())) {
572 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
573 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
574 listShape.Append(It.Value());
579 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
580 for (; exp.More(); exp.Next())
581 if (mapShape.Add(exp.Current()))
582 listShape.Append(exp.Current());
585 if (listShape.IsEmpty()) {
586 SetErrorCode("The given shape has no sub-shapes of the requested type");
591 SortShapes(listShape);
593 TopTools_IndexedMapOfShape anIndices;
594 TopExp::MapShapes(aShape, anIndices);
595 Handle(TColStd_HArray1OfInteger) anArray;
597 TopTools_ListIteratorOfListOfShape itSub (listShape);
598 TCollection_AsciiString anAsciiList, anEntry;
599 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
600 TopoDS_Shape aValue = itSub.Value();
601 anArray = new TColStd_HArray1OfInteger(1,1);
602 anArray->SetValue(1, anIndices.FindIndex(aValue));
603 anObj = GetEngine()->AddSubShape(theShape, anArray);
606 // for python command
607 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
608 anAsciiList += anEntry;
612 //Make a Python command
613 anAsciiList.Trunc(anAsciiList.Length() - 1);
615 aFunction = theShape->GetLastFunction();
617 GEOM::TPythonDump pd (aFunction, /*append=*/true);
618 pd << "[" << anAsciiList.ToCString();
619 pd << "] = geompy.SubShapeAll" << (isSorted ? "Sorted(" : "(");
620 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
627 //=============================================================================
631 //=============================================================================
632 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::SubShapeAllIDs
633 (Handle(GEOM_Object) theShape,
634 const Standard_Integer theShapeType,
635 const Standard_Boolean isSorted)
639 if (theShape.IsNull()) return NULL;
640 TopoDS_Shape aShape = theShape->GetValue();
641 if (aShape.IsNull()) return NULL;
643 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
644 TopTools_MapOfShape mapShape;
645 TopTools_ListOfShape listShape;
647 if (aShape.ShapeType() == TopAbs_COMPOUND &&
648 (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
649 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPSOLID ||
650 TopAbs_ShapeEnum(theShapeType) == TopAbs_COMPOUND)) {
651 TopoDS_Iterator It (aShape, Standard_True, Standard_True);
652 for (; It.More(); It.Next()) {
653 if (mapShape.Add(It.Value())) {
654 if (TopAbs_ShapeEnum(theShapeType) == TopAbs_SHAPE ||
655 TopAbs_ShapeEnum(theShapeType) == It.Value().ShapeType()) {
656 listShape.Append(It.Value());
661 TopExp_Explorer exp (aShape, TopAbs_ShapeEnum(theShapeType));
662 for (; exp.More(); exp.Next())
663 if (mapShape.Add(exp.Current()))
664 listShape.Append(exp.Current());
667 if (listShape.IsEmpty()) {
668 SetErrorCode("The given shape has no sub-shapes of the requested type");
673 SortShapes(listShape);
675 TopTools_IndexedMapOfShape anIndices;
676 TopExp::MapShapes(aShape, anIndices);
677 Handle(TColStd_HArray1OfInteger) anArray;
679 TopTools_ListIteratorOfListOfShape itSub (listShape);
680 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
681 TopoDS_Shape aValue = itSub.Value();
682 aSeq->Append(anIndices.FindIndex(aValue));
685 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
687 //Make a Python command
688 GEOM::TPythonDump pd (aFunction, /*append=*/true);
689 pd << "listSubShapeIDs = geompy.SubShapeAll";
690 pd << (isSorted ? "SortedIDs(" : "IDs(");
691 pd << theShape << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
697 //=============================================================================
701 //=============================================================================
702 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetSubShape
703 (Handle(GEOM_Object) theMainShape,
704 const Standard_Integer theID)
708 if (theMainShape.IsNull()) return NULL;
710 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
711 anArray->SetValue(1, theID);
712 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theMainShape, anArray,true);
713 if (anObj.IsNull()) {
714 SetErrorCode("Can not get a sub-shape with the given ID");
718 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
720 //Make a Python command
721 GEOM::TPythonDump(aFunction) << anObj << " = geompy.GetSubShape("
722 << theMainShape << ", [" << theID << "])";
728 //=============================================================================
732 //=============================================================================
733 Standard_Integer GEOMImpl_IShapesOperations::GetSubShapeIndex (Handle(GEOM_Object) theMainShape,
734 Handle(GEOM_Object) theSubShape)
738 TopoDS_Shape aMainShape = theMainShape->GetValue();
739 TopoDS_Shape aSubShape = theSubShape->GetValue();
741 if (aMainShape.IsNull() || aSubShape.IsNull()) return -1;
743 TopTools_IndexedMapOfShape anIndices;
744 TopExp::MapShapes(aMainShape, anIndices);
745 if (anIndices.Contains(aSubShape)) {
747 return anIndices.FindIndex(aSubShape);
753 //=============================================================================
757 //=============================================================================
758 Standard_Integer GEOMImpl_IShapesOperations::GetTopologyIndex (Handle(GEOM_Object) theMainShape,
759 Handle(GEOM_Object) theSubShape)
763 TopoDS_Shape aMainShape = theMainShape->GetValue();
764 TopoDS_Shape aSubShape = theSubShape->GetValue();
766 if (aMainShape.IsNull() || aSubShape.IsNull()) {
767 SetErrorCode("Null argument shape given");
772 if (aSubShape.ShapeType() == TopAbs_COMPOUND) {
774 TopTools_ListOfShape CL;
775 CL.Append(aMainShape);
776 TopTools_ListIteratorOfListOfShape itC;
777 for (itC.Initialize(CL); itC.More(); itC.Next()) {
778 for (it.Initialize(itC.Value()); it.More(); it.Next()) {
779 if (it.Value().ShapeType() == TopAbs_COMPOUND) {
780 if (it.Value().IsSame(aSubShape))
784 CL.Append(it.Value());
789 TopExp_Explorer anExp (aMainShape, aSubShape.ShapeType());
790 TopTools_MapOfShape M;
791 for (; anExp.More(); anExp.Next()) {
792 if (M.Add(anExp.Current())) {
793 if (anExp.Current().IsSame(aSubShape))
800 SetErrorCode("The sub-shape does not belong to the main shape");
804 //=============================================================================
808 //=============================================================================
809 TCollection_AsciiString GEOMImpl_IShapesOperations::GetShapeTypeString (Handle(GEOM_Object) theShape)
813 TCollection_AsciiString aTypeName ("Null Shape");
815 TopoDS_Shape aShape = theShape->GetValue();
819 switch (aShape.ShapeType() )
821 case TopAbs_COMPOUND:
822 aTypeName = "Compound";
824 case TopAbs_COMPSOLID:
825 aTypeName = "Compound Solid";
835 BRepAdaptor_Surface surf (TopoDS::Face(aShape));
836 if (surf.GetType() == GeomAbs_Plane)
838 else if (surf.GetType() == GeomAbs_Cylinder)
839 aTypeName = "Cylindrical Face";
840 else if (surf.GetType() == GeomAbs_Sphere)
841 aTypeName = "Spherical Face";
842 else if (surf.GetType() == GeomAbs_Torus)
843 aTypeName = "Toroidal Face";
844 else if (surf.GetType() == GeomAbs_Cone)
845 aTypeName = "Conical Face";
847 aTypeName = "GEOM::FACE";
855 BRepAdaptor_Curve curv (TopoDS::Edge(aShape));
856 if (curv.GetType() == GeomAbs_Line) {
857 if ((Abs(curv.FirstParameter()) >= 1E6) ||
858 (Abs(curv.LastParameter()) >= 1E6))
862 } else if (curv.GetType() == GeomAbs_Circle) {
864 aTypeName = "Circle";
873 aTypeName = "Vertex";
879 aTypeName = "Shape of unknown type";
886 //=============================================================================
890 //=============================================================================
891 Standard_Integer GEOMImpl_IShapesOperations::NumberOfFaces (Handle(GEOM_Object) theShape)
895 Standard_Integer nb = 0;
897 if (theShape.IsNull()) return -1;
898 TopoDS_Shape aShape = theShape->GetValue();
899 if (aShape.IsNull()) return -1;
901 TopTools_MapOfShape mapShape;
903 TopExp_Explorer exp (aShape, TopAbs_FACE);
904 for (; exp.More(); exp.Next())
905 if (mapShape.Add(exp.Current()))
912 //=============================================================================
916 //=============================================================================
917 Standard_Integer GEOMImpl_IShapesOperations::NumberOfEdges (Handle(GEOM_Object) theShape)
921 Standard_Integer nb = 0;
923 if (theShape.IsNull()) return -1;
924 TopoDS_Shape aShape = theShape->GetValue();
925 if (aShape.IsNull()) return -1;
927 TopTools_MapOfShape mapShape;
929 TopExp_Explorer exp (aShape, TopAbs_EDGE);
930 for (; exp.More(); exp.Next())
931 if (mapShape.Add(exp.Current()))
938 //=============================================================================
942 //=============================================================================
943 Handle(GEOM_Object) GEOMImpl_IShapesOperations::ReverseShape(Handle(GEOM_Object) theShape)
947 if (theShape.IsNull()) return NULL;
949 //Add a new reversed object
950 Handle(GEOM_Object) aReversed = GetEngine()->AddObject(GetDocID(), theShape->GetType());
952 //Add a new Revese function
953 Handle(GEOM_Function) aFunction;
954 aFunction = aReversed->AddFunction(GEOMImpl_ShapeDriver::GetID(), REVERSE_ORIENTATION);
955 if (aFunction.IsNull()) return NULL;
957 //Check if the function is set correctly
958 if (aFunction->GetDriverGUID() != GEOMImpl_ShapeDriver::GetID()) return NULL;
960 GEOMImpl_IShapes aSI (aFunction);
962 Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
963 if (aRefShape.IsNull()) return NULL;
965 aSI.SetBase(aRefShape);
967 //Compute the sub-shape value
969 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
972 if (!GetSolver()->ComputeFunction(aFunction)) {
973 SetErrorCode("Shape driver failed to reverse shape");
977 catch (Standard_Failure) {
978 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
979 SetErrorCode(aFail->GetMessageString());
983 //Make a Python command
984 GEOM::TPythonDump(aFunction) << aReversed
985 << " = geompy.ChangeOrientation(" << theShape << ")";
991 //=============================================================================
995 //=============================================================================
996 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetFreeFacesIDs
997 (Handle(GEOM_Object) theShape)
1001 if (theShape.IsNull()) return NULL;
1002 TopoDS_Shape aShape = theShape->GetValue();
1003 if (aShape.IsNull()) return NULL;
1005 Handle(TColStd_HSequenceOfInteger) aSeq = new TColStd_HSequenceOfInteger;
1007 TopTools_IndexedDataMapOfShapeListOfShape mapFaceBlocks;
1008 GEOMImpl_Block6Explorer::MapShapesAndAncestors
1009 (aShape, TopAbs_FACE, TopAbs_SOLID, mapFaceBlocks);
1011 Standard_Integer ind = 1, nbFaces = mapFaceBlocks.Extent();
1014 SetErrorCode("The given shape has no faces");
1018 TopTools_IndexedMapOfShape anIndices;
1019 TopExp::MapShapes(aShape, anIndices);
1021 Standard_Integer id;
1022 for (; ind <= nbFaces; ind++) {
1023 if (mapFaceBlocks.FindFromIndex(ind).Extent() != 2) {
1024 id = anIndices.FindIndex(mapFaceBlocks.FindKey(ind));
1029 //The explode doesn't change object so no new function is required.
1030 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1032 //Make a Python command
1033 GEOM::TPythonDump(aFunction, /*append=*/true)
1034 << "listFreeFacesIDs = geompy.GetFreeFacesIDs(" << theShape << ")";
1040 //=======================================================================
1041 //function : GetSharedShapes
1043 //=======================================================================
1045 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetSharedShapes
1046 (Handle(GEOM_Object) theShape1,
1047 Handle(GEOM_Object) theShape2,
1048 const Standard_Integer theShapeType)
1052 if (theShape1.IsNull() || theShape2.IsNull()) return NULL;
1054 TopoDS_Shape aShape1 = theShape1->GetValue();
1055 TopoDS_Shape aShape2 = theShape2->GetValue();
1057 if (aShape1.IsNull() || aShape2.IsNull()) return NULL;
1059 TopTools_IndexedMapOfShape anIndices;
1060 TopExp::MapShapes(aShape1, anIndices);
1061 Handle(TColStd_HArray1OfInteger) anArray;
1063 TopTools_IndexedMapOfShape mapShape1;
1064 TopExp::MapShapes(aShape1, TopAbs_ShapeEnum(theShapeType), mapShape1);
1066 Handle(GEOM_Object) anObj;
1067 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1068 TCollection_AsciiString anAsciiList, anEntry;
1070 TopTools_MapOfShape mapShape2;
1071 TopExp_Explorer exp (aShape2, TopAbs_ShapeEnum(theShapeType));
1072 for (; exp.More(); exp.Next()) {
1073 TopoDS_Shape aSS = exp.Current();
1074 if (mapShape2.Add(aSS) && mapShape1.Contains(aSS)) {
1075 anArray = new TColStd_HArray1OfInteger(1,1);
1076 anArray->SetValue(1, anIndices.FindIndex(aSS));
1077 anObj = GetEngine()->AddSubShape(theShape1, anArray);
1078 aSeq->Append(anObj);
1080 // for python command
1081 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1082 anAsciiList += anEntry;
1087 if (aSeq->IsEmpty()) {
1088 SetErrorCode("The given shapes have no shared sub-shapes of the requested type");
1092 //Make a Python command
1093 anAsciiList.Trunc(anAsciiList.Length() - 1);
1095 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1097 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1098 << "] = geompy.GetSharedShapes(" << theShape1 << ", "
1099 << theShape2 << ", " << TopAbs_ShapeEnum(theShapeType) << ")";
1105 //=============================================================================
1109 //=============================================================================
1110 static GEOM::TPythonDump& operator<< (GEOM::TPythonDump& theDump,
1111 const GEOMAlgo_State theState)
1114 case GEOMAlgo_ST_IN:
1115 theDump << "geompy.GEOM.ST_IN";
1117 case GEOMAlgo_ST_OUT:
1118 theDump << "geompy.GEOM.ST_OUT";
1120 case GEOMAlgo_ST_ON:
1121 theDump << "geompy.GEOM.ST_ON";
1123 case GEOMAlgo_ST_ONIN:
1124 theDump << "geompy.GEOM.ST_ONIN";
1126 case GEOMAlgo_ST_ONOUT:
1127 theDump << "geompy.GEOM.ST_ONOUT";
1130 theDump << "geompy.GEOM.ST_UNKNOWN";
1136 //=======================================================================
1137 //function : checkTypeShapesOn
1139 * \brief Checks if theShapeType parameter of GetShapesOnXXX() is OK
1140 * \param theShapeType - the shape type to check
1141 * \retval bool - result of the check
1143 //=======================================================================
1145 bool GEOMImpl_IShapesOperations::checkTypeShapesOn(const Standard_Integer theShapeType)
1147 if (theShapeType != TopAbs_VERTEX &&
1148 theShapeType != TopAbs_EDGE &&
1149 theShapeType != TopAbs_FACE &&
1150 theShapeType != TopAbs_SOLID) {
1151 SetErrorCode("Only solids, vertices, edges or faces can be found by this method");
1157 //=======================================================================
1158 //function : makePlane
1160 * \brief Creates Geom_Plane
1161 * \param theAx1 - shape object defining plane parameters
1162 * \retval Handle(Geom_Surface) - resulting surface
1164 //=======================================================================
1166 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makePlane(const TopoDS_Shape& anAx1)
1168 if (anAx1.ShapeType() != TopAbs_EDGE) return NULL;
1169 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1170 TopoDS_Vertex V1, V2;
1171 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1172 if (V1.IsNull() || V2.IsNull()) {
1173 SetErrorCode("Bad edge given for the plane normal vector");
1176 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1177 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1178 if (aVec.Magnitude() < Precision::Confusion()) {
1179 SetErrorCode("Vector with null magnitude given");
1182 return new Geom_Plane(aLoc, aVec);
1185 //=======================================================================
1186 //function : makeCylinder
1188 * \brief Creates Geom_CylindricalSurface
1189 * \param theAx1 - edge defining cylinder axis
1190 * \param theRadius - cylinder radius
1191 * \retval Handle(Geom_Surface) - resulting surface
1193 //=======================================================================
1195 Handle(Geom_Surface) GEOMImpl_IShapesOperations::makeCylinder(const TopoDS_Shape& anAxis,
1196 const Standard_Real theRadius)
1198 //Axis of the cylinder
1199 if (anAxis.ShapeType() != TopAbs_EDGE) {
1200 SetErrorCode("Not an edge given for the axis");
1203 TopoDS_Edge anEdge = TopoDS::Edge(anAxis);
1204 TopoDS_Vertex V1, V2;
1205 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1206 if (V1.IsNull() || V2.IsNull()) {
1207 SetErrorCode("Bad edge given for the axis");
1210 gp_Pnt aLoc = BRep_Tool::Pnt(V1);
1211 gp_Vec aVec (aLoc, BRep_Tool::Pnt(V2));
1212 if (aVec.Magnitude() < Precision::Confusion()) {
1213 SetErrorCode("Vector with null magnitude given");
1217 gp_Ax3 anAx3 (aLoc, aVec);
1218 return new Geom_CylindricalSurface(anAx3, theRadius);
1222 //=======================================================================
1223 //function : getShapesOnSurfaceIDs
1225 * \brief Find IDs of subshapes complying with given status about surface
1226 * \param theSurface - the surface to check state of subshapes against
1227 * \param theShape - the shape to explore
1228 * \param theShapeType - type of subshape of theShape
1229 * \param theState - required state
1230 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1232 //=======================================================================
1234 Handle(TColStd_HSequenceOfInteger)
1235 GEOMImpl_IShapesOperations::getShapesOnSurfaceIDs(const Handle(Geom_Surface)& theSurface,
1236 const TopoDS_Shape& theShape,
1237 TopAbs_ShapeEnum theShapeType,
1238 GEOMAlgo_State theState)
1240 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1242 // Check presence of triangulation, build if need
1243 if (!CheckTriangulation(theShape))
1247 GEOMAlgo_FinderShapeOn1 aFinder;
1248 Standard_Real aTol = 0.0001; // default value
1250 aFinder.SetShape(theShape);
1251 aFinder.SetTolerance(aTol);
1252 aFinder.SetSurface(theSurface);
1253 aFinder.SetShapeType(theShapeType);
1254 aFinder.SetState(theState);
1256 // Sets the minimal number of inner points for the faces that do not have own
1257 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1259 aFinder.SetNbPntsMin(3);
1260 // Sets the maximal number of inner points for edges or faces.
1261 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1262 // the performance. If this value =0, all inner points will be taken into account.
1264 aFinder.SetNbPntsMax(100);
1268 // Interprete results
1269 Standard_Integer iErr = aFinder.ErrorStatus();
1270 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1272 MESSAGE(" iErr : " << iErr);
1273 TCollection_AsciiString aMsg (" iErr : ");
1274 aMsg += TCollection_AsciiString(iErr);
1278 Standard_Integer iWrn = aFinder.WarningStatus();
1279 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1281 MESSAGE(" *** iWrn : " << iWrn);
1284 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1286 if (listSS.Extent() < 1) {
1287 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1291 // Fill sequence of object IDs
1292 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1294 TopTools_IndexedMapOfShape anIndices;
1295 TopExp::MapShapes(theShape, anIndices);
1297 TopTools_ListIteratorOfListOfShape itSub (listSS);
1298 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1299 int id = anIndices.FindIndex(itSub.Value());
1300 aSeqOfIDs->Append(id);
1306 //=======================================================================
1307 //function : getObjectsShapesOn
1309 * \brief Find shape objects and their entries by their ids
1310 * \param theShapeIDs - incoming shape ids
1311 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1312 * \retval Handle(TColStd_HSequenceOfTransient) - found shape objects
1314 //=======================================================================
1316 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::
1317 getObjectsShapesOn(const Handle(GEOM_Object)& theShape,
1318 const Handle(TColStd_HSequenceOfInteger)& theShapeIDs,
1319 TCollection_AsciiString & theShapeEntries)
1321 Handle(TColStd_HSequenceOfTransient) aSeq;
1323 if ( !theShapeIDs.IsNull() && theShapeIDs->Length() > 0 )
1325 aSeq = new TColStd_HSequenceOfTransient;
1326 Handle(TColStd_HArray1OfInteger) anArray = new TColStd_HArray1OfInteger(1,1);
1327 TCollection_AsciiString anEntry;
1328 for ( int i = 1; i <= theShapeIDs->Length(); ++i )
1330 anArray->SetValue(1, theShapeIDs->Value( i ));
1331 Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(theShape, anArray);
1332 aSeq->Append( anObj );
1334 TDF_Tool::Entry(anObj->GetEntry(), anEntry);
1335 if ( i != 1 ) theShapeEntries += ",";
1336 theShapeEntries += anEntry;
1342 //=======================================================================
1343 //function : getShapesOnSurface
1345 * \brief Find subshapes complying with given status about surface
1346 * \param theSurface - the surface to check state of subshapes against
1347 * \param theShape - the shape to explore
1348 * \param theShapeType - type of subshape of theShape
1349 * \param theState - required state
1350 * \param theShapeEntries - outgoing entries like "entry1, entry2, ..."
1351 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1353 //=======================================================================
1355 Handle(TColStd_HSequenceOfTransient)
1356 GEOMImpl_IShapesOperations::getShapesOnSurface(const Handle(Geom_Surface)& theSurface,
1357 const Handle(GEOM_Object)& theShape,
1358 TopAbs_ShapeEnum theShapeType,
1359 GEOMAlgo_State theState,
1360 TCollection_AsciiString & theShapeEntries)
1362 // Find subshapes ids
1363 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1364 getShapesOnSurfaceIDs (theSurface, theShape->GetValue(), theShapeType, theState);
1365 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->Length() == 0 )
1368 return getObjectsShapesOn( theShape, aSeqOfIDs, theShapeEntries );
1371 //=============================================================================
1375 //=============================================================================
1376 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlane
1377 (const Handle(GEOM_Object)& theShape,
1378 const Standard_Integer theShapeType,
1379 const Handle(GEOM_Object)& theAx1,
1380 const GEOMAlgo_State theState)
1384 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1386 TopoDS_Shape aShape = theShape->GetValue();
1387 TopoDS_Shape anAx1 = theAx1->GetValue();
1389 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1391 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1392 if ( !checkTypeShapesOn( theShapeType ))
1396 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1397 if ( aPlane.IsNull() )
1401 TCollection_AsciiString anAsciiList;
1402 Handle(TColStd_HSequenceOfTransient) aSeq;
1403 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1404 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1407 // Make a Python command
1409 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1410 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1412 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1413 << "] = geompy.GetShapesOnPlane(" << theShape << ", "
1414 << aShapeType << ", " << theAx1 << ", " << theState << ")";
1420 //=============================================================================
1422 * GetShapesOnPlaneWithLocation
1424 //=============================================================================
1425 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocation
1426 (const Handle(GEOM_Object)& theShape,
1427 const Standard_Integer theShapeType,
1428 const Handle(GEOM_Object)& theAx1,
1429 const Handle(GEOM_Object)& thePnt,
1430 const GEOMAlgo_State theState)
1434 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
1436 TopoDS_Shape aShape = theShape->GetValue();
1437 TopoDS_Shape anAx1 = theAx1->GetValue();
1438 TopoDS_Shape anPnt = thePnt->GetValue();
1440 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
1442 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1443 if ( !checkTypeShapesOn( theShapeType ))
1447 if ( anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX ) return NULL;
1448 TopoDS_Vertex V1, V2, V3;
1449 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1450 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1452 if (V1.IsNull() || V2.IsNull()) {
1453 SetErrorCode("Bad edge given for the plane normal vector");
1456 V3 = TopoDS::Vertex(anPnt);
1459 SetErrorCode("Bad vertex given for the plane location");
1462 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
1463 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
1465 if (aVec.Magnitude() < Precision::Confusion()) {
1466 SetErrorCode("Vector with null magnitude given");
1469 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
1471 if ( aPlane.IsNull() )
1475 TCollection_AsciiString anAsciiList;
1476 Handle(TColStd_HSequenceOfTransient) aSeq;
1477 aSeq = getShapesOnSurface( aPlane, theShape, aShapeType, theState, anAsciiList );
1478 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1481 // Make a Python command
1483 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1484 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1486 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1487 << "] = geompy.GetShapesOnPlaneWithLocation(" << theShape << ", "
1488 << aShapeType << ", " << theAx1 << ", "<< thePnt <<", " << theState << ")";
1494 //=============================================================================
1496 * GetShapesOnCylinder
1498 //=============================================================================
1499 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnCylinder
1500 (const Handle(GEOM_Object)& theShape,
1501 const Standard_Integer theShapeType,
1502 const Handle(GEOM_Object)& theAxis,
1503 const Standard_Real theRadius,
1504 const GEOMAlgo_State theState)
1508 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1510 TopoDS_Shape aShape = theShape->GetValue();
1511 TopoDS_Shape anAxis = theAxis->GetValue();
1513 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1515 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1516 if ( !checkTypeShapesOn( aShapeType ))
1519 // Create a cylinder surface
1520 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1521 if ( aCylinder.IsNull() )
1525 TCollection_AsciiString anAsciiList;
1526 Handle(TColStd_HSequenceOfTransient) aSeq;
1527 aSeq = getShapesOnSurface( aCylinder, theShape, aShapeType, theState, anAsciiList );
1528 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1531 // Make a Python command
1533 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1534 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1536 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1537 << "] = geompy.GetShapesOnCylinder(" << theShape << ", " << aShapeType
1538 << ", " << theAxis << ", " << theRadius << ", " << theState << ")";
1544 //=============================================================================
1548 //=============================================================================
1549 Handle(TColStd_HSequenceOfTransient) GEOMImpl_IShapesOperations::GetShapesOnSphere
1550 (const Handle(GEOM_Object)& theShape,
1551 const Standard_Integer theShapeType,
1552 const Handle(GEOM_Object)& theCenter,
1553 const Standard_Real theRadius,
1554 const GEOMAlgo_State theState)
1558 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1560 TopoDS_Shape aShape = theShape->GetValue();
1561 TopoDS_Shape aCenter = theCenter->GetValue();
1563 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1565 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1566 if ( !checkTypeShapesOn( aShapeType ))
1569 // Center of the sphere
1570 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1571 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1573 gp_Ax3 anAx3 (aLoc, gp::DZ());
1574 Handle(Geom_SphericalSurface) aSphere =
1575 new Geom_SphericalSurface(anAx3, theRadius);
1578 TCollection_AsciiString anAsciiList;
1579 Handle(TColStd_HSequenceOfTransient) aSeq;
1580 aSeq = getShapesOnSurface( aSphere, theShape, aShapeType, theState, anAsciiList );
1581 if ( aSeq.IsNull() || aSeq->Length() == 0 )
1584 // Make a Python command
1586 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1587 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1589 GEOM::TPythonDump(aFunction) << "[" << anAsciiList.ToCString()
1590 << "] = geompy.GetShapesOnSphere(" << theShape << ", " << aShapeType
1591 << ", " << theCenter << ", " << theRadius << ", " << theState << ")";
1597 //=============================================================================
1599 * GetShapesOnPlaneIDs
1601 //=============================================================================
1602 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneIDs
1603 (const Handle(GEOM_Object)& theShape,
1604 const Standard_Integer theShapeType,
1605 const Handle(GEOM_Object)& theAx1,
1606 const GEOMAlgo_State theState)
1610 if (theShape.IsNull() || theAx1.IsNull()) return NULL;
1612 TopoDS_Shape aShape = theShape->GetValue();
1613 TopoDS_Shape anAx1 = theAx1->GetValue();
1615 if (aShape.IsNull() || anAx1.IsNull()) return NULL;
1617 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1618 if ( !checkTypeShapesOn( aShapeType ))
1622 Handle(Geom_Surface) aPlane = makePlane( anAx1 );
1623 if ( aPlane.IsNull() )
1627 Handle(TColStd_HSequenceOfInteger) aSeq;
1628 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1630 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1631 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
1633 // Make a Python command
1634 GEOM::TPythonDump(aFunction, /*append=*/true)
1635 << "listShapesOnPlane = geompy.GetShapesOnPlaneIDs"
1636 << "(" << theShape << "," << aShapeType << "," << theAx1 << "," << theState << ")";
1642 //=============================================================================
1644 * GetShapesOnPlaneWithLocationIDs
1646 //=============================================================================
1647 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnPlaneWithLocationIDs
1648 (const Handle(GEOM_Object)& theShape,
1649 const Standard_Integer theShapeType,
1650 const Handle(GEOM_Object)& theAx1,
1651 const Handle(GEOM_Object)& thePnt,
1652 const GEOMAlgo_State theState)
1656 if (theShape.IsNull() || theAx1.IsNull() || thePnt.IsNull()) return NULL;
1658 TopoDS_Shape aShape = theShape->GetValue();
1659 TopoDS_Shape anAx1 = theAx1->GetValue();
1660 TopoDS_Shape anPnt = thePnt->GetValue();
1662 if (aShape.IsNull() || anAx1.IsNull() || anPnt.IsNull()) return NULL;
1664 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1665 if ( !checkTypeShapesOn( aShapeType ))
1669 if (anAx1.ShapeType() != TopAbs_EDGE || anPnt.ShapeType() != TopAbs_VERTEX) return NULL;
1670 TopoDS_Edge anEdge = TopoDS::Edge(anAx1);
1671 TopoDS_Vertex V1, V2, V3;
1672 TopExp::Vertices(anEdge, V1, V2, Standard_True);
1673 if (V1.IsNull() || V2.IsNull()) {
1674 SetErrorCode("Bad edge given for the plane normal vector");
1677 V3 = TopoDS::Vertex(anPnt);
1679 SetErrorCode("Bad vertex given for the plane location");
1682 gp_Pnt aLoc = BRep_Tool::Pnt(V3);
1683 gp_Vec aVec(BRep_Tool::Pnt(V1),BRep_Tool::Pnt(V2));
1684 if (aVec.Magnitude() < Precision::Confusion()) {
1685 SetErrorCode("Vector with null magnitude given");
1689 Handle(Geom_Surface) aPlane = new Geom_Plane(aLoc, aVec);
1690 if ( aPlane.IsNull() )
1694 Handle(TColStd_HSequenceOfInteger) aSeq;
1695 aSeq = getShapesOnSurfaceIDs( aPlane, aShape, aShapeType, theState );
1697 // The GetShapesOnPlaneIDs() doesn't change object so no new function is required.
1698 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAx1)->GetLastFunction();
1700 // Make a Python command
1701 GEOM::TPythonDump(aFunction, /*append=*/true)
1702 << "listShapesOnPlane = geompy.GetShapesOnPlaneWithLocationIDs"
1703 << "(" << theShape << ", " << aShapeType << ", " << theAx1 << ", "<< thePnt << ", " << theState << ")";
1709 //=============================================================================
1711 * GetShapesOnCylinderIDs
1713 //=============================================================================
1714 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnCylinderIDs
1715 (const Handle(GEOM_Object)& theShape,
1716 const Standard_Integer theShapeType,
1717 const Handle(GEOM_Object)& theAxis,
1718 const Standard_Real theRadius,
1719 const GEOMAlgo_State theState)
1723 if (theShape.IsNull() || theAxis.IsNull()) return NULL;
1725 TopoDS_Shape aShape = theShape->GetValue();
1726 TopoDS_Shape anAxis = theAxis->GetValue();
1728 if (aShape.IsNull() || anAxis.IsNull()) return NULL;
1730 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1731 if ( !checkTypeShapesOn( aShapeType ))
1734 // Create a cylinder surface
1735 Handle(Geom_Surface) aCylinder = makeCylinder( anAxis, theRadius );
1736 if ( aCylinder.IsNull() )
1740 Handle(TColStd_HSequenceOfInteger) aSeq;
1741 aSeq = getShapesOnSurfaceIDs( aCylinder, aShape, aShapeType, theState );
1743 // The GetShapesOnCylinder() doesn't change object so no new function is required.
1744 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theAxis)->GetLastFunction();
1746 // Make a Python command
1747 GEOM::TPythonDump(aFunction, /*append=*/true)
1748 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1749 << "(" << theShape << ", " << aShapeType << ", " << theAxis << ", "
1750 << theRadius << ", " << theState << ")";
1756 //=============================================================================
1758 * GetShapesOnSphereIDs
1760 //=============================================================================
1761 Handle(TColStd_HSequenceOfInteger) GEOMImpl_IShapesOperations::GetShapesOnSphereIDs
1762 (const Handle(GEOM_Object)& theShape,
1763 const Standard_Integer theShapeType,
1764 const Handle(GEOM_Object)& theCenter,
1765 const Standard_Real theRadius,
1766 const GEOMAlgo_State theState)
1770 if (theShape.IsNull() || theCenter.IsNull()) return NULL;
1772 TopoDS_Shape aShape = theShape->GetValue();
1773 TopoDS_Shape aCenter = theCenter->GetValue();
1775 if (aShape.IsNull() || aCenter.IsNull()) return NULL;
1777 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1778 if ( !checkTypeShapesOn( aShapeType ))
1781 // Center of the sphere
1782 if (aCenter.ShapeType() != TopAbs_VERTEX) return NULL;
1783 gp_Pnt aLoc = BRep_Tool::Pnt(TopoDS::Vertex(aCenter));
1785 gp_Ax3 anAx3 (aLoc, gp::DZ());
1786 Handle(Geom_SphericalSurface) aSphere =
1787 new Geom_SphericalSurface(anAx3, theRadius);
1790 Handle(TColStd_HSequenceOfInteger) aSeq;
1791 aSeq = getShapesOnSurfaceIDs( aSphere, aShape, aShapeType, theState );
1793 // The GetShapesOnSphere() doesn't change object so no new function is required.
1794 Handle(GEOM_Function) aFunction = GEOM::GetCreatedLast(theShape,theCenter)->GetLastFunction();
1796 // Make a Python command
1797 GEOM::TPythonDump(aFunction, /*append=*/true)
1798 << "listShapesOnCylinder = geompy.GetShapesOnCylinderIDs"
1799 << "(" << theShape << ", " << aShapeType << ", " << theCenter << ", "
1800 << theRadius << ", " << theState << ")";
1806 //=======================================================================
1807 //function : getShapesOnQuadrangleIDs
1809 * \brief Find IDs of subshapes complying with given status about quadrangle
1810 * \param theShape - the shape to explore
1811 * \param theShapeType - type of subshape of theShape
1812 * \param theTopLeftPoint - top left quadrangle corner
1813 * \param theTopRigthPoint - top right quadrangle corner
1814 * \param theBottomLeftPoint - bottom left quadrangle corner
1815 * \param theBottomRigthPoint - bottom right quadrangle corner
1816 * \param theState - required state
1817 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1819 //=======================================================================
1821 Handle(TColStd_HSequenceOfInteger)
1822 GEOMImpl_IShapesOperations::getShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
1823 const Standard_Integer theShapeType,
1824 const Handle(GEOM_Object)& theTopLeftPoint,
1825 const Handle(GEOM_Object)& theTopRigthPoint,
1826 const Handle(GEOM_Object)& theBottomLeftPoint,
1827 const Handle(GEOM_Object)& theBottomRigthPoint,
1828 const GEOMAlgo_State theState)
1832 if ( theShape.IsNull() ||
1833 theTopLeftPoint.IsNull() ||
1834 theTopRigthPoint.IsNull() ||
1835 theBottomLeftPoint.IsNull() ||
1836 theBottomRigthPoint.IsNull() )
1839 TopoDS_Shape aShape = theShape->GetValue();
1840 TopoDS_Shape aTL = theTopLeftPoint->GetValue();
1841 TopoDS_Shape aTR = theTopRigthPoint->GetValue();
1842 TopoDS_Shape aBL = theBottomLeftPoint->GetValue();
1843 TopoDS_Shape aBR = theBottomRigthPoint->GetValue();
1845 if (aShape.IsNull() ||
1850 aTL.ShapeType() != TopAbs_VERTEX ||
1851 aTR.ShapeType() != TopAbs_VERTEX ||
1852 aBL.ShapeType() != TopAbs_VERTEX ||
1853 aBR.ShapeType() != TopAbs_VERTEX )
1856 TopAbs_ShapeEnum aShapeType = TopAbs_ShapeEnum(theShapeType);
1857 if ( !checkTypeShapesOn( aShapeType ))
1860 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs;
1862 // Check presence of triangulation, build if need
1863 if (!CheckTriangulation(aShape))
1867 gp_Pnt aPntTL = BRep_Tool::Pnt(TopoDS::Vertex(aTL));
1868 gp_Pnt aPntTR = BRep_Tool::Pnt(TopoDS::Vertex(aTR));
1869 gp_Pnt aPntBL = BRep_Tool::Pnt(TopoDS::Vertex(aBL));
1870 gp_Pnt aPntBR = BRep_Tool::Pnt(TopoDS::Vertex(aBR));
1872 GEOMAlgo_FinderShapeOnQuad aFinder( aPntTL, aPntTR, aPntBL, aPntBR );
1873 Standard_Real aTol = 0.0001; // default value
1875 aFinder.SetShape(aShape);
1876 aFinder.SetTolerance(aTol);
1877 //aFinder.SetSurface(theSurface);
1878 aFinder.SetShapeType(aShapeType);
1879 aFinder.SetState(theState);
1881 // Sets the minimal number of inner points for the faces that do not have own
1882 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
1884 aFinder.SetNbPntsMin(3);
1885 // Sets the maximal number of inner points for edges or faces.
1886 // It is usefull for the cases when this number is very big (e.g =2000) to improve
1887 // the performance. If this value =0, all inner points will be taken into account.
1889 aFinder.SetNbPntsMax(100);
1893 // Interprete results
1894 Standard_Integer iErr = aFinder.ErrorStatus();
1895 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
1897 MESSAGE(" iErr : " << iErr);
1898 TCollection_AsciiString aMsg (" iErr : ");
1899 aMsg += TCollection_AsciiString(iErr);
1903 Standard_Integer iWrn = aFinder.WarningStatus();
1904 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
1906 MESSAGE(" *** iWrn : " << iWrn);
1909 const TopTools_ListOfShape& listSS = aFinder.Shapes(); // the result
1911 if (listSS.Extent() < 1) {
1912 SetErrorCode("Not a single sub-shape of the requested type found on the given surface");
1916 // Fill sequence of object IDs
1917 aSeqOfIDs = new TColStd_HSequenceOfInteger;
1919 TopTools_IndexedMapOfShape anIndices;
1920 TopExp::MapShapes(aShape, anIndices);
1922 TopTools_ListIteratorOfListOfShape itSub (listSS);
1923 for (int index = 1; itSub.More(); itSub.Next(), ++index) {
1924 int id = anIndices.FindIndex(itSub.Value());
1925 aSeqOfIDs->Append(id);
1930 //=======================================================================
1931 //function : GetShapesOnQuadrangle
1933 * \brief Find subshapes complying with given status about quadrangle
1934 * \param theShape - the shape to explore
1935 * \param theShapeType - type of subshape of theShape
1936 * \param theTopLeftPoint - top left quadrangle corner
1937 * \param theTopRigthPoint - top right quadrangle corner
1938 * \param theBottomLeftPoint - bottom left quadrangle corner
1939 * \param theBottomRigthPoint - bottom right quadrangle corner
1940 * \param theState - required state
1941 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
1943 //=======================================================================
1945 Handle(TColStd_HSequenceOfTransient)
1946 GEOMImpl_IShapesOperations::GetShapesOnQuadrangle (const Handle(GEOM_Object)& theShape,
1947 const Standard_Integer theShapeType,
1948 const Handle(GEOM_Object)& theTopLeftPoint,
1949 const Handle(GEOM_Object)& theTopRigthPoint,
1950 const Handle(GEOM_Object)& theBottomLeftPoint,
1951 const Handle(GEOM_Object)& theBottomRigthPoint,
1952 const GEOMAlgo_State theState)
1955 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
1956 getShapesOnQuadrangleIDs( theShape,
1961 theBottomRigthPoint,
1963 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
1966 // Find objects by indices
1967 TCollection_AsciiString anAsciiList;
1968 Handle(TColStd_HSequenceOfTransient) aSeq;
1969 aSeq = getObjectsShapesOn( theShape, aSeqOfIDs, anAsciiList );
1970 if ( aSeq.IsNull() || aSeq->IsEmpty() )
1973 // Make a Python command
1975 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast( aSeq->Value( 1 ));
1976 Handle(GEOM_Function) aFunction = anObj->GetLastFunction();
1978 GEOM::TPythonDump(aFunction)
1979 << "[" << anAsciiList.ToCString() << "] = geompy.GetShapesOnQuadrangle("
1981 << TopAbs_ShapeEnum(theShapeType) << ", "
1982 << theTopLeftPoint << ", "
1983 << theTopRigthPoint << ", "
1984 << theBottomLeftPoint << ", "
1985 << theBottomRigthPoint << ", "
1992 //=======================================================================
1993 //function : GetShapesOnQuadrangleIDs
1995 * \brief Find IDs of subshapes complying with given status about quadrangle
1996 * \param theShape - the shape to explore
1997 * \param theShapeType - type of subshape of theShape
1998 * \param theTopLeftPoint - top left quadrangle corner
1999 * \param theTopRigthPoint - top right quadrangle corner
2000 * \param theBottomLeftPoint - bottom left quadrangle corner
2001 * \param theBottomRigthPoint - bottom right quadrangle corner
2002 * \param theState - required state
2003 * \retval Handle(TColStd_HSequenceOfInteger) - IDs of found subshapes
2005 //=======================================================================
2007 Handle(TColStd_HSequenceOfInteger)
2008 GEOMImpl_IShapesOperations::GetShapesOnQuadrangleIDs (const Handle(GEOM_Object)& theShape,
2009 const Standard_Integer theShapeType,
2010 const Handle(GEOM_Object)& theTopLeftPoint,
2011 const Handle(GEOM_Object)& theTopRigthPoint,
2012 const Handle(GEOM_Object)& theBottomLeftPoint,
2013 const Handle(GEOM_Object)& theBottomRigthPoint,
2014 const GEOMAlgo_State theState)
2017 Handle(TColStd_HSequenceOfInteger) aSeqOfIDs =
2018 getShapesOnQuadrangleIDs( theShape,
2023 theBottomRigthPoint,
2025 if ( aSeqOfIDs.IsNull() || aSeqOfIDs->IsEmpty() )
2028 // Make a Python command
2030 // The GetShapesOnCylinder() doesn't change object so no new function is required.
2031 Handle(GEOM_Object) lastObj = GEOM::GetCreatedLast(theShape,theTopLeftPoint);
2032 lastObj = GEOM::GetCreatedLast(lastObj,theTopRigthPoint);
2033 lastObj = GEOM::GetCreatedLast(lastObj,theBottomRigthPoint);
2034 lastObj = GEOM::GetCreatedLast(lastObj,theBottomLeftPoint);
2035 Handle(GEOM_Function) aFunction = lastObj->GetLastFunction();
2037 GEOM::TPythonDump(aFunction, /*append=*/true)
2038 << "listShapesOnQuadrangle = geompy.GetShapesOnQuadrangleIDs("
2040 << TopAbs_ShapeEnum(theShapeType) << ", "
2041 << theTopLeftPoint << ", "
2042 << theTopRigthPoint << ", "
2043 << theBottomLeftPoint << ", "
2044 << theBottomRigthPoint << ", "
2052 //=============================================================================
2056 //=============================================================================
2057 static void SimplifyWhat (TopoDS_Shape& theWhat,
2058 TopTools_IndexedMapOfShape& theArgumentIndices,
2059 TColStd_ListOfInteger& theSimpleSubWhat)
2061 TopTools_MapOfShape mapShape;
2062 TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
2063 for (; It.More(); It.Next()) {
2064 if (mapShape.Add(It.Value())) {
2065 TopoDS_Shape curSh = It.Value();
2066 if (curSh.ShapeType() == TopAbs_COMPOUND ||
2067 curSh.ShapeType() == TopAbs_COMPSOLID) {
2068 SimplifyWhat(curSh, theArgumentIndices, theSimpleSubWhat);
2070 theSimpleSubWhat.Append(theArgumentIndices.FindIndex(curSh));
2076 static bool GetInPlaceOfCompound (Handle(GEOM_Function)& theWhereFunction,
2077 TopoDS_Shape& theWhat,
2078 TColStd_ListOfInteger& theModifiedArray)
2080 bool isFoundAny = false;
2081 TopTools_MapOfShape mapShape;
2082 TopoDS_Iterator It (theWhat, Standard_True, Standard_True);
2083 for (; It.More(); It.Next()) {
2084 if (mapShape.Add(It.Value())) {
2085 TopoDS_Shape curWhat = It.Value();
2086 if (curWhat.ShapeType() == TopAbs_COMPOUND ||
2087 curWhat.ShapeType() == TopAbs_COMPSOLID) {
2088 // Recursive call for compound or compsolid
2089 if (GetInPlaceOfCompound(theWhereFunction, curWhat, theModifiedArray))
2092 // Try to find for "simple" shape
2093 bool isFound = false;
2095 TDF_LabelSequence aLabelSeq;
2096 theWhereFunction->GetDependency(aLabelSeq);
2097 Standard_Integer nbArg = aLabelSeq.Length();
2099 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2101 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2103 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2104 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2106 TopTools_IndexedMapOfShape anArgumentIndices;
2107 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2109 if (anArgumentIndices.Contains(curWhat)) {
2110 isFound = Standard_True;
2111 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(curWhat);
2113 // Find corresponding label in history
2114 TDF_Label anArgumentHistoryLabel =
2115 theWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2116 if (!anArgumentHistoryLabel.IsNull()) {
2117 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2118 if (!aWhatHistoryLabel.IsNull()) {
2119 Handle(TDataStd_IntegerArray) anIntegerArray;
2120 if (aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2121 Standard_Integer imod, aModifLen = anIntegerArray->Array()->Length();
2122 for (imod = 1; imod <= aModifLen; imod++) {
2123 theModifiedArray.Append(anIntegerArray->Array()->Value(imod));
2138 Handle(GEOM_Object) GEOMImpl_IShapesOperations::GetInPlace
2139 (Handle(GEOM_Object) theShapeWhere,
2140 Handle(GEOM_Object) theShapeWhat)
2144 if (theShapeWhere.IsNull() || theShapeWhat.IsNull()) return NULL;
2146 TopoDS_Shape aWhere = theShapeWhere->GetValue();
2147 TopoDS_Shape aWhat = theShapeWhat->GetValue();
2149 if (aWhere.IsNull() || aWhat.IsNull()) return NULL;
2151 //Fill array of indices
2152 Handle(TColStd_HArray1OfInteger) aModifiedArray;
2154 Handle(GEOM_Function) aWhereFunction = theShapeWhere->GetLastFunction();
2156 TopTools_IndexedMapOfShape aWhereIndices;
2157 TopExp::MapShapes(aWhere, aWhereIndices);
2159 if (aWhereIndices.Contains(aWhat)) {
2161 // entity was not changed by the operation
2162 Standard_Integer aWhatIndex = aWhereIndices.FindIndex(aWhat);
2163 aModifiedArray = new TColStd_HArray1OfInteger(1,1);
2164 aModifiedArray->SetValue(1, aWhatIndex);
2168 TDF_Label aHistoryLabel = aWhereFunction->GetHistoryEntry(Standard_False);
2169 if (aHistoryLabel.IsNull()) {
2170 SetErrorCode("Modifications history does not exist for the shape under consideration.");
2174 // search in history for all argument shapes
2175 Standard_Boolean isFound = Standard_False;
2177 TDF_LabelSequence aLabelSeq;
2178 aWhereFunction->GetDependency(aLabelSeq);
2179 Standard_Integer nbArg = aLabelSeq.Length();
2181 for (Standard_Integer iarg = 1; iarg <= nbArg && !isFound; iarg++) {
2183 TDF_Label anArgumentRefLabel = aLabelSeq.Value(iarg);
2185 Handle(GEOM_Object) anArgumentObject = GEOM_Object::GetReferencedObject(anArgumentRefLabel);
2186 TopoDS_Shape anArgumentShape = anArgumentObject->GetValue();
2188 TopTools_IndexedMapOfShape anArgumentIndices;
2189 TopExp::MapShapes(anArgumentShape, anArgumentIndices);
2191 if (anArgumentIndices.Contains(aWhat)) {
2192 isFound = Standard_True;
2193 Standard_Integer aWhatIndex = anArgumentIndices.FindIndex(aWhat);
2195 // Find corresponding label in history
2196 TDF_Label anArgumentHistoryLabel =
2197 aWhereFunction->GetArgumentHistoryEntry(anArgumentRefLabel, Standard_False);
2198 if (anArgumentHistoryLabel.IsNull()) {
2199 // Lost History of operation argument. Possibly, all its entities was removed.
2204 TDF_Label aWhatHistoryLabel = anArgumentHistoryLabel.FindChild(aWhatIndex, Standard_False);
2205 if (aWhatHistoryLabel.IsNull()) {
2206 // Check, if the sought shape is Compound or Compsolid.
2207 // In that case we will try to find history for its sub-shapes
2208 if (aWhat.ShapeType() == TopAbs_COMPOUND ||
2209 aWhat.ShapeType() == TopAbs_COMPSOLID) {
2210 TColStd_ListOfInteger aSimpleSubWhat, aModifiedList;
2211 SimplifyWhat(aWhat, anArgumentIndices, aSimpleSubWhat);
2212 TColStd_ListIteratorOfListOfInteger anIterSub (aSimpleSubWhat);
2213 for (; anIterSub.More(); anIterSub.Next()) {
2214 Standard_Integer aSubWhatIndex = anIterSub.Value();
2215 TDF_Label aSubWhatHistoryLabel =
2216 anArgumentHistoryLabel.FindChild(aSubWhatIndex, Standard_False);
2217 if (!aSubWhatHistoryLabel.IsNull()) {
2218 Handle(TDataStd_IntegerArray) anIntegerArray;
2219 if (aSubWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2220 for (Standard_Integer isub = 1; isub <= anIntegerArray->Length(); isub++) {
2221 aModifiedList.Append(anIntegerArray->Value(isub));
2226 if (aModifiedList.Extent() > 0) {
2227 Handle(TColStd_HArray1OfInteger) aModifiedArraySub =
2228 new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2229 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2230 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2231 aModifiedArraySub->SetValue(imod, anIterModif.Value());
2233 aModifiedArray = aModifiedArraySub;
2245 Handle(TDataStd_IntegerArray) anIntegerArray;
2246 if (!aWhatHistoryLabel.FindAttribute(TDataStd_IntegerArray::GetID(), anIntegerArray)) {
2247 SetErrorCode("Error: Empty modifications history for the sought shape.");
2251 aModifiedArray = anIntegerArray->Array();
2252 if (aModifiedArray->Length() == 0) {
2253 SetErrorCode("Error: Empty modifications history for the sought shape.");
2261 // try compound element by element
2262 if (aWhat.ShapeType() == TopAbs_COMPOUND ||
2263 aWhat.ShapeType() == TopAbs_COMPSOLID) {
2264 TColStd_ListOfInteger aModifiedList;
2265 isFound = GetInPlaceOfCompound(aWhereFunction, aWhat, aModifiedList);
2267 aModifiedArray = new TColStd_HArray1OfInteger (1, aModifiedList.Extent());
2268 TColStd_ListIteratorOfListOfInteger anIterModif (aModifiedList);
2269 for (Standard_Integer imod = 1; anIterModif.More(); anIterModif.Next(), imod++) {
2270 aModifiedArray->SetValue(imod, anIterModif.Value());
2275 SetErrorCode("The sought shape does not belong to any operation argument.");
2282 Handle(GEOM_Object) aResult = GetEngine()->AddSubShape(theShapeWhere, aModifiedArray);
2284 if (aModifiedArray->Length() > 1) {
2286 aResult->SetType(GEOM_GROUP);
2288 //Set a sub shape type
2289 TDF_Label aFreeLabel = aResult->GetFreeLabel();
2290 TopAbs_ShapeEnum aShapeType = aWhat.ShapeType();
2291 TDataStd_Integer::Set(aFreeLabel, (Standard_Integer)aShapeType);
2294 //Make a Python command
2295 Handle(GEOM_Function) aFunction = aResult->GetFunction(1);
2297 GEOM::TPythonDump(aFunction) << aResult << " = geompy.GetInPlace("
2298 << theShapeWhere << ", " << theShapeWhat << ")";
2304 //=======================================================================
2305 //function : SortShapes
2307 //=======================================================================
2308 void GEOMImpl_IShapesOperations::SortShapes(TopTools_ListOfShape& SL)
2310 Standard_Integer MaxShapes = SL.Extent();
2311 TopTools_Array1OfShape aShapes (1,MaxShapes);
2312 TColStd_Array1OfInteger OrderInd(1,MaxShapes);
2313 TColStd_Array1OfReal MidXYZ (1,MaxShapes); //X,Y,Z;
2314 TColStd_Array1OfReal Length (1,MaxShapes); //X,Y,Z;
2316 // Computing of CentreOfMass
2317 Standard_Integer Index;
2320 TopTools_ListIteratorOfListOfShape it(SL);
2321 for (Index=1; it.More(); Index++)
2323 TopoDS_Shape S = it.Value();
2324 SL.Remove( it ); // == it.Next()
2326 OrderInd.SetValue (Index, Index);
2327 if (S.ShapeType() == TopAbs_VERTEX)
2329 GPoint = BRep_Tool::Pnt( TopoDS::Vertex( S ));
2330 Length.SetValue( Index, (Standard_Real) S.Orientation());
2334 BRepGProp::LinearProperties (S, GPr);
2335 GPoint = GPr.CentreOfMass();
2336 Length.SetValue( Index, GPr.Mass() );
2338 MidXYZ.SetValue(Index,
2339 GPoint.X()*999 + GPoint.Y()*99 + GPoint.Z()*0.9);
2343 Standard_Integer aTemp;
2344 Standard_Boolean exchange, Sort = Standard_True;
2347 Sort = Standard_False;
2348 for (Index=1; Index < MaxShapes; Index++)
2350 if (MidXYZ(OrderInd(Index)) > MidXYZ(OrderInd(Index+1)))
2351 exchange = Standard_True;
2352 else if (MidXYZ(OrderInd(Index)) == MidXYZ(OrderInd(Index+1)) &&
2353 Length(OrderInd(Index)) > Length(OrderInd(Index+1)) )
2354 exchange = Standard_True;
2356 exchange = Standard_False;
2359 aTemp = OrderInd(Index);
2360 OrderInd(Index) = OrderInd(Index+1);
2361 OrderInd(Index+1) = aTemp;
2362 Sort = Standard_True;
2366 for (Index=1; Index <= MaxShapes; Index++)
2367 SL.Append( aShapes( OrderInd(Index) ));
2370 //=======================================================================
2371 //function : CheckTriangulation
2373 //=======================================================================
2374 bool GEOMImpl_IShapesOperations::CheckTriangulation (const TopoDS_Shape& aShape)
2376 TopExp_Explorer exp (aShape, TopAbs_FACE);
2378 SetErrorCode("Shape without faces given");
2382 TopLoc_Location aTopLoc;
2383 Handle(Poly_Triangulation) aTRF;
2384 aTRF = BRep_Tool::Triangulation(TopoDS::Face(exp.Current()), aTopLoc);
2385 if (aTRF.IsNull()) {
2386 // calculate deflection
2387 Standard_Real aDeviationCoefficient = 0.001;
2390 BRepBndLib::Add(aShape, B);
2391 Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax;
2392 B.Get(aXmin, aYmin, aZmin, aXmax, aYmax, aZmax);
2394 Standard_Real dx = aXmax - aXmin, dy = aYmax - aYmin, dz = aZmax - aZmin;
2395 Standard_Real aDeflection = Max(Max(dx, dy), dz) * aDeviationCoefficient * 4;
2396 Standard_Real aHLRAngle = 0.349066;
2398 BRepMesh_IncrementalMesh Inc (aShape, aDeflection, Standard_False, aHLRAngle);