1 // Copyright (C) 2007-2014 CEA/DEN, EDF R&D, OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // File : GEOMImpl_IAdvancedOperations.cxx
20 // Author : Vadim SANDLER, Open CASCADE S.A.S. (vadim.sandler@opencascade.com)
22 #include "GEOMImpl_IAdvancedOperations.hxx"
24 #include <Basics_OCCTVersion.hxx>
26 #include <utilities.h>
28 #include <Utils_ExceptHandlers.hxx>
30 #include "GEOM_Function.hxx"
31 #include "GEOM_PythonDump.hxx"
32 #include "GEOMUtils.hxx"
33 #include "GEOMAlgo_Splitter.hxx"
34 #include "GEOMAlgo_FinderShapeOn1.hxx"
36 #include "GEOMImpl_Gen.hxx"
37 #include "GEOMImpl_Types.hxx"
39 #include "GEOMImpl_IBasicOperations.hxx"
40 #include "GEOMImpl_IBooleanOperations.hxx"
41 #include "GEOMImpl_IShapesOperations.hxx"
42 #include "GEOMImpl_ITransformOperations.hxx"
43 #include "GEOMImpl_IBlocksOperations.hxx"
44 #include "GEOMImpl_I3DPrimOperations.hxx"
45 #include "GEOMImpl_ILocalOperations.hxx"
46 #include "GEOMImpl_IHealingOperations.hxx"
47 #include "GEOMImpl_IGroupOperations.hxx"
49 #include "GEOMImpl_GlueDriver.hxx"
50 #include "GEOMImpl_PipeTShapeDriver.hxx"
51 #include "GEOMImpl_IPipeTShape.hxx"
52 #include "GEOMImpl_DividedDiskDriver.hxx"
53 #include "GEOMImpl_IDividedDisk.hxx"
54 #include <GEOMImpl_SmoothingSurfaceDriver.hxx>
55 #include <GEOMImpl_ISmoothingSurface.hxx>
56 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/
58 #include <TDF_Tool.hxx>
59 #include <TFunction_DriverTable.hxx>
60 #include <TFunction_Driver.hxx>
61 #include <TFunction_Logbook.hxx>
62 #include <TNaming_CopyShape.hxx>
65 #include <TopExp_Explorer.hxx>
67 #include <TopoDS_Vertex.hxx>
68 #include <TopTools_IndexedMapOfShape.hxx>
69 #include <TopTools_ListIteratorOfListOfShape.hxx>
70 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
72 #include <BRep_Builder.hxx>
73 #include <BRep_Tool.hxx>
75 #include <BRepAdaptor_Surface.hxx>
76 #include <BRepAlgoAPI_Cut.hxx>
77 #include <BRepAlgoAPI_Fuse.hxx>
78 #include <BRepBuilderAPI_MakeFace.hxx>
79 #include <BRepBuilderAPI_MakeVertex.hxx>
80 #include <BRepBuilderAPI_Transform.hxx>
81 #include <BRepPrimAPI_MakeCone.hxx>
82 #include <BRepPrimAPI_MakeCylinder.hxx>
88 #include <GC_MakeConicalSurface.hxx>
89 #include <Geom_CylindricalSurface.hxx>
91 #include <ShapeAnalysis_Edge.hxx>
95 #include "AdvancedEngine_Types.hxx"
97 #include <Standard_Stream.hxx>
98 #include <Standard_Failure.hxx>
99 #include <StdFail_NotDone.hxx>
100 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
102 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
103 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
104 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
105 #define THICKNESS "Thickness" //"Epaisseur"
106 #define FLANGE "Flange" // "Collerette"
107 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
108 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
109 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
110 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
112 #define FIND_GROUPS_BY_POINTS 1
114 //=============================================================================
118 //=============================================================================
119 GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations(GEOM_Engine* theEngine, int theDocID) :
120 GEOM_IOperations(theEngine, theDocID)
122 MESSAGE("GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations");
123 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
124 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
125 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
126 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
127 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
128 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
129 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
130 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
131 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
134 //=============================================================================
138 //=============================================================================
139 GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations()
141 MESSAGE("GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations");
142 delete myBasicOperations;
143 delete myBooleanOperations;
144 delete myShapesOperations;
145 delete myTransformOperations;
146 delete myBlocksOperations;
147 delete my3DPrimOperations;
148 delete myLocalOperations;
149 delete myHealingOperations;
150 delete myGroupOperations;
153 //=============================================================================
157 //=============================================================================
158 gp_Trsf GEOMImpl_IAdvancedOperations::GetPositionTrsf(double theL1, double theL2,
159 Handle(GEOM_Object) theP1,
160 Handle(GEOM_Object) theP2,
161 Handle(GEOM_Object) theP3)
163 // Old Local Coordinates System oldLCS
165 gp_Pnt P1(-theL1, 0, 0);
166 gp_Pnt P2(theL1, 0, 0);
167 gp_Pnt P3(0, 0, theL2);
169 gp_Dir oldX(gp_Vec(P1, P2));
170 gp_Dir oldZ(gp_Vec(P0, P3));
171 gp_Ax3 oldLCS(P0, oldZ, oldX);
173 // New Local Coordinates System newLCS
174 double LocX, LocY, LocZ;
175 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
176 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
177 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
178 LocX = (newP1.X() + newP2.X()) / 2.;
179 LocY = (newP1.Y() + newP2.Y()) / 2.;
180 LocZ = (newP1.Z() + newP2.Z()) / 2.;
181 gp_Pnt newO(LocX, LocY, LocZ);
183 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
184 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
185 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
188 aTrsf.SetDisplacement(oldLCS, newLCS);
193 //=============================================================================
195 * CheckCompatiblePosition
198 //=============================================================================
199 bool GEOMImpl_IAdvancedOperations::CheckCompatiblePosition(double& theL1, double& theL2,
200 Handle(GEOM_Object) theP1,
201 Handle(GEOM_Object) theP2,
202 Handle(GEOM_Object) theP3,
206 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
207 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
208 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
210 double d12 = P1.Distance(P2);
211 double d13 = P1.Distance(P3);
212 double d23 = P2.Distance(P3);
213 // double d2 = newO.Distance(P3);
215 if (Abs(d12) <= Precision::Confusion()) {
216 SetErrorCode("Junctions points P1 and P2 are identical");
219 if (Abs(d13) <= Precision::Confusion()) {
220 SetErrorCode("Junctions points P1 and P3 are identical");
223 if (Abs(d23) <= Precision::Confusion()) {
224 SetErrorCode("Junctions points P2 and P3 are identical");
229 double newL1 = 0.5 * d12;
230 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
232 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
234 if (fabs(newL1 - theL1) > Precision::Approximation()) {
235 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
236 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
237 // std::cerr << "theL1 = newL1" << std::endl;
241 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
247 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
249 if (fabs(newL2 - theL2) > Precision::Approximation()) {
250 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
251 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
255 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
265 //=============================================================================
267 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
269 //=============================================================================
270 bool GEOMImpl_IAdvancedOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
271 double theR1, double theW1, double theL1,
272 double theR2, double theW2, double theL2,
273 double theH, double theW, double theRF,
274 Handle(TColStd_HSequenceOfTransient) theSeq,
279 if (theShape.IsNull()) return false;
281 TopoDS_Shape aShape = theShape->GetValue();
282 if (aShape.IsNull()) {
283 SetErrorCode("Shape is not defined");
287 gp_Trsf aTrsfInv = aTrsf.Inverted();
289 // int expectedGroups = 0;
290 // if (shapeType == TSHAPE_BASIC)
291 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
292 // expectedGroups = 10;
294 // expectedGroups = 11;
295 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
296 // expectedGroups = 12;
298 double aR1Ext = theR1 + theW1;
299 double aR2Ext = theR2 + theW2;
301 /////////////////////////
302 //// Groups of Faces ////
303 /////////////////////////
306 // Comment the following lines when GetInPlace bug is solved
308 // Workaround of GetInPlace bug
309 // Create a bounding box that fits the shape
310 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
311 aBox->GetLastFunction()->SetDescription("");
312 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
313 aBox->GetLastFunction()->SetDescription("");
314 // Apply transformation to box
315 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
316 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
317 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
319 // Get the shell of the box
320 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
321 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
322 aBox->GetLastFunction()->SetDescription("");
323 aShell->GetLastFunction()->SetDescription("");
324 // Get the common shapes between shell and shape
325 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean
326 (theShape, aShell, 1, Standard_False); // MakeCommon
327 if (aCommonCompound.IsNull()) {
328 SetErrorCode(myBooleanOperations->GetErrorCode());
331 aCommonCompound->GetLastFunction()->SetDescription("");
332 // Explode the faces of common shapes => 3 faces
333 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
334 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
335 aCommonCompound->GetLastFunction()->SetDescription("");
336 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
338 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
339 std::list<Handle(GEOM_Object)> aFacesList;
340 for (int j = 1 ; j <= 4 ; j++) {
341 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
342 if (!aFace.IsNull()) {
343 aFace->GetLastFunction()->SetDescription("");
344 aFacesList.push_back(aFace);
347 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
348 if (!aCompoundOfFaces.IsNull()) {
349 aCompoundOfFaces->GetLastFunction()->SetDescription("");
350 aCompoundOfFacesList.push_back(aCompoundOfFaces);
354 if (aCompoundOfFacesList.size() == 3) {
355 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
356 aCompoundOfFacesList.pop_front();
357 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
358 aCompoundOfFacesList.pop_front();
359 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
360 aCompoundOfFacesList.pop_front();
365 // Uncomment the following lines when GetInPlace bug is solved
367 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
368 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
369 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
370 // aP1->GetLastFunction()->SetDescription("");
371 // aP2->GetLastFunction()->SetDescription("");
372 // aP3->GetLastFunction()->SetDescription("");
373 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
374 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
375 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
376 // aV1->GetLastFunction()->SetDescription("");
377 // aV2->GetLastFunction()->SetDescription("");
378 // aV3->GetLastFunction()->SetDescription("");
379 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
380 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
381 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
382 // aPln1->GetLastFunction()->SetDescription("");
383 // aPln2->GetLastFunction()->SetDescription("");
384 // aPln3->GetLastFunction()->SetDescription("");
386 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
387 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
388 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
389 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
390 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
391 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
392 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
393 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
394 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
398 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
399 if (junctionFaces1.IsNull())
400 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
401 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
402 if (!junctionFaces1.IsNull()) {
403 junctionFaces1->GetLastFunction()->SetDescription("");
404 junctionFaces1->SetName("JUNCTION_FACE_1");
405 theSeq->Append(junctionFaces1);
408 SetErrorCode("Junction face 1 not found");
409 // theSeq->Append(aPln1);
412 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
413 if (junctionFaces2.IsNull())
414 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
415 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
416 if (!junctionFaces2.IsNull()) {
417 junctionFaces2->GetLastFunction()->SetDescription("");
418 junctionFaces2->SetName("JUNCTION_FACE_2");
419 theSeq->Append(junctionFaces2);
422 SetErrorCode("Junction face 2 not found");
423 // theSeq->Append(aPln2);
426 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
427 if (junctionFaces3.IsNull())
428 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
429 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
430 if (!junctionFaces3.IsNull()) {
431 junctionFaces3->GetLastFunction()->SetDescription("");
432 junctionFaces3->SetName("JUNCTION_FACE_3");
433 theSeq->Append(junctionFaces3);
436 SetErrorCode("Junction face 3 not found");
437 // theSeq->Append(aPln3);
440 // Comment the following lines when GetInPlace bug is solved
445 /////////////////////////
446 //// Groups of Edges ////
447 /////////////////////////
448 // Result of propagate
450 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
452 TCollection_AsciiString theDesc = aFunction->GetDescription();
453 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
454 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
455 SetErrorCode("Propagation groups not found");
458 Standard_Integer aNbGroups = aSeqPropagate->Length();
459 // Recover previous description to get rid of Propagate dump
460 aFunction->SetDescription(theDesc);
462 #ifdef FIND_GROUPS_BY_POINTS
463 // BEGIN: new groups search
470 // g / ''..| | |..'' \
472 // .---.--'.. | | | ..'--.---.
473 // |a \ '''...........''' / |
474 // |-------\------' | '------/-------.
479 // ._________________|_________________.
485 // |-----------------|-----------------|
487 // '-----------------'-----------------'
490 // "Thickness" group (a)
491 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
492 aPntA.Transform(aTrsf);
493 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
494 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
495 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
497 // "Circular quarter of pipe" group (b)
498 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
499 aPntB.Transform(aTrsf);
500 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
501 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
502 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
504 // "Circular quarter of pipe" group (c)
505 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
506 aPntC.Transform(aTrsf);
507 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
508 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
509 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
511 // "Main pipe half length" group (d)
512 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
513 aPntD.Transform(aTrsf);
514 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
515 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
516 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
518 // "Incident pipe half length" group (e)
519 double aTol10 = Precision::Confusion() * 10.;
520 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
521 aPntE.Transform(aTrsf);
522 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
523 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
524 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
526 // "Flange" group (f)
527 double aFx = - aR2Ext - aTol10;
528 if (shapeType == TSHAPE_CHAMFER)
530 else if (shapeType == TSHAPE_FILLET)
532 gp_Pnt aPntF (aFx, 0, aR1Ext);
533 aPntF.Transform(aTrsf);
534 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
535 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
536 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
538 // "Chamfer or Fillet" group (g)
539 TopoDS_Shape anEdgeG;
540 if (shapeType == TSHAPE_CHAMFER) {
541 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
542 aPntG.Transform(aTrsf);
543 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
544 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
545 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
547 else if (shapeType == TSHAPE_FILLET) {
548 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
549 aPntG.Transform(aTrsf);
550 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
551 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
552 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
555 for (int i = 1 ; i <= aNbGroups; i++) {
556 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
560 TopoDS_Shape aGroupShape = aGroup->GetValue();
561 TopTools_IndexedMapOfShape anEdgesMap;
562 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
564 if (anEdgesMap.Contains(anEdgeA)) { // a
565 aGroup->SetName("THICKNESS");
566 theSeq->Append(aGroup);
568 else if (anEdgesMap.Contains(anEdgeB)) { // b
569 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
570 theSeq->Append(aGroup);
572 else if (anEdgesMap.Contains(anEdgeC)) { // c
573 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
574 theSeq->Append(aGroup);
576 else if (anEdgesMap.Contains(anEdgeD)) { // d
577 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
578 theSeq->Append(aGroup);
580 else if (anEdgesMap.Contains(anEdgeE)) { // e
581 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
582 theSeq->Append(aGroup);
584 else if (anEdgesMap.Contains(anEdgeF)) { // f
585 aGroup->SetName("FLANGE");
586 theSeq->Append(aGroup);
588 else if (shapeType == TSHAPE_CHAMFER) { // g
589 if (anEdgesMap.Contains(anEdgeG)) {
590 aGroup->SetName("CHAMFER");
591 theSeq->Append(aGroup);
594 else if (shapeType == TSHAPE_FILLET) { // g
595 if (anEdgesMap.Contains(anEdgeG)) {
596 aGroup->SetName("FILLET");
597 theSeq->Append(aGroup);
603 // END: new groups search
606 bool circularFoundAndAdded = false;
607 bool circularFound10 = false;
608 bool incidentPipeFound = false;
609 bool mainPipeFound = false;
610 bool mainPipeFoundAndAdded = false;
611 bool radialFound =false;
612 bool flangeFound = false;
613 bool flangeFoundAndAdded = false;
614 bool chamferOrFilletFound = false;
616 for (int i = 1 ; i <= aNbGroups; i++) {
619 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
623 TopoDS_Shape aGroupShape = aGroup->GetValue();
624 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
625 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
627 TopTools_IndexedMapOfShape anEdgesMap;
628 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
629 Standard_Integer nbEdges = anEdgesMap.Extent();
631 if (shapeType == TSHAPE_BASIC) {
632 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
634 aGroup->SetName("THICKNESS");
636 else if (nbEdges == 6) {
637 if (!circularFoundAndAdded) {
638 circularFoundAndAdded = true;
640 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
643 else if (nbEdges == 8) {
644 incidentPipeFound = true;
645 mainPipeFound = false;
649 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
651 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
652 double x=aP.X(), y=aP.Y(), z=aP.Z();
655 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
656 (Abs(y) > aR2Ext + Precision::Confusion())) {
657 incidentPipeFound = false;
660 if ( z < -Precision::Confusion()) {
661 // length of main pipe
662 mainPipeFound = true;
663 if (!mainPipeFoundAndAdded) {
664 mainPipeFoundAndAdded = true;
666 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
670 else if (Abs(x) > (theL1-Precision::Confusion())) {
671 // discretisation circulaire
673 if (!circularFoundAndAdded) {
674 circularFoundAndAdded = true;
676 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
681 if (incidentPipeFound) {
683 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
685 if (!addGroup && (!incidentPipeFound &&
689 // Flange (collerette)
692 aGroup->SetName("FLANGE");
698 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
699 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
701 aGroup->SetName("THICKNESS");
703 else if ((nbEdges == 10) || (nbEdges == 6)) {
704 if (!circularFoundAndAdded) {
706 circularFoundAndAdded = true;
707 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
709 circularFound10 = true;
712 else if (!circularFound10 && nbEdges == 10) {
713 circularFound10 = true;
715 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
718 else if (nbEdges == 8) {
719 incidentPipeFound = true;
720 mainPipeFound = true;
723 bool isNearZ0 = false;
724 bool isBelowZ0 = false;
726 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
728 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
729 double x=aP.X(), y=aP.Y(), z=aP.Z();
731 // tuy_princ_long_avant & tuy_princ_long_apres
732 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
733 // ((y <= aR1Ext + Precision::Confusion()) ||
734 // (y <= -(aR1Ext + Precision::Confusion())) ||
735 // (y <= theR1 + Precision::Confusion()) ||
736 // (y == -(theR1 + Precision::Confusion()))));
737 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
738 (fabs(y) > theR1 - Precision::Confusion() ||
739 fabs(y) < Precision::Confusion()));
742 mainPipeFound = false;
746 //if (z < Precision::Confusion() && !isMain) {
747 // flangeFound = true;
748 // if (!flangeFoundAndAdded) {
749 // flangeFoundAndAdded = true;
751 // aGroup->SetName("FLANGE");
754 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
755 if (z < - Precision::Confusion()) isBelowZ0 = true;
758 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
759 (Abs(y) > aR2Ext + Precision::Confusion())) {
760 incidentPipeFound = false;
766 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
768 if (incidentPipeFound) {
770 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
772 if (isNearZ0 && !isBelowZ0) {
774 if (!flangeFoundAndAdded) {
775 flangeFoundAndAdded = true;
777 aGroup->SetName("FLANGE");
780 if (!addGroup && (!incidentPipeFound &&
783 !chamferOrFilletFound)) {
785 chamferOrFilletFound = true;
786 if (shapeType == TSHAPE_CHAMFER)
787 aGroup->SetName("CHAMFER");
789 aGroup->SetName("FILLET");
795 // Add group to the list
797 theSeq->Append(aGroup);
805 //=============================================================================
807 * Return faces that are laying on surface.
809 //=============================================================================
810 bool GEOMImpl_IAdvancedOperations::GetFacesOnSurf
811 (const TopoDS_Shape &theShape,
812 const Handle_Geom_Surface& theSurface,
813 const Standard_Real theTolerance,
814 TopTools_ListOfShape &theFaces)
816 GEOMAlgo_FinderShapeOn1 aFinder;
818 aFinder.SetShape(theShape);
819 aFinder.SetTolerance(theTolerance);
820 aFinder.SetSurface(theSurface);
821 aFinder.SetShapeType(TopAbs_FACE);
822 aFinder.SetState(GEOMAlgo_ST_ON);
824 // Sets the minimal number of inner points for the faces that do not have own
825 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
827 aFinder.SetNbPntsMin(3);
828 // Sets the maximal number of inner points for edges or faces.
829 // It is usefull for the cases when this number is very big (e.g =2000) to improve
830 // the performance. If this value =0, all inner points will be taken into account.
832 aFinder.SetNbPntsMax(100);
835 // Interprete results
836 Standard_Integer iErr = aFinder.ErrorStatus();
837 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
839 MESSAGE(" iErr : " << iErr);
840 TCollection_AsciiString aMsg (" iErr : ");
841 aMsg += TCollection_AsciiString(iErr);
845 Standard_Integer iWrn = aFinder.WarningStatus();
846 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
848 MESSAGE(" *** iWrn : " << iWrn);
851 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
852 TopTools_ListIteratorOfListOfShape anIter (aListRes);
854 for (; anIter.More(); anIter.Next()) {
855 theFaces.Append(anIter.Value());
861 //=============================================================================
863 * Creates and returns conical face.
865 //=============================================================================
866 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakeConicalFace
867 (const gp_Ax2 &theAxis,
868 const double theRadius,
869 const double theRadiusThin,
870 const double theHeight,
871 const gp_Trsf &theTrsf)
873 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
874 TopoDS_Shape aResult;
877 if (aMkCone.IsDone()) {
878 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
880 for (; anExp.More(); anExp.Next()) {
881 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
883 if (aFace.IsNull() == Standard_False) {
884 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
886 if (anAdaptor.GetType() == GeomAbs_Cone) {
887 // This is a conical face. Transform and return it.
888 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
890 aResult = aTransf.Shape();
900 //=============================================================================
902 * Generate the internal group of a Pipe T-Shape
904 //=============================================================================
905 bool GEOMImpl_IAdvancedOperations::MakeInternalGroup
906 (const Handle(GEOM_Object) &theShape,
907 const double theR1, const double theLen1,
908 const double theR2, const double theLen2,
909 const double theRL, double theTransLenL,
910 const double theRR, double theTransLenR,
911 const double theRI, double theTransLenI,
912 const Handle(TColStd_HSequenceOfTransient) &theSeq,
913 const gp_Trsf &theTrsf)
917 if (theShape.IsNull()) {
921 TopoDS_Shape aShape = theShape->GetValue();
923 if (aShape.IsNull()) {
924 SetErrorCode("Shape is not defined");
929 Standard_Real aMaxTol = -RealLast();
930 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
932 for (; anExp.More(); anExp.Next()) {
933 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
935 if (aVertex.IsNull() == Standard_False) {
936 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
938 if (aTol > aMaxTol) {
944 // Construct internal surfaces.
945 Standard_Integer i = 0;
946 const Standard_Integer aMaxNbSurf = 5;
947 Handle(Geom_Surface) aSurface[aMaxNbSurf];
948 TopTools_ListOfShape aConicalFaces;
949 Standard_Real aTolConf = Precision::Confusion();
951 // 1. Construct the internal surface of main pipe.
952 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
953 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
955 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
957 // 2. Construct the internal surface of incident pipe.
958 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
960 // 3. Construct the internal surface of left reduction pipe.
961 if (theRL > aTolConf) {
962 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
964 if (theTransLenL > aTolConf) {
965 // 3.1. Construct the internal surface of left transition pipe.
966 gp_Pnt aPLeft (-theLen1, 0., 0.);
967 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
968 TopoDS_Shape aConeLeft =
969 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
971 if (aConeLeft.IsNull() == Standard_False) {
972 aConicalFaces.Append(aConeLeft);
977 // 4. Construct the internal surface of right reduction pipe.
978 if (theRR > aTolConf) {
979 // There is no need to construct another cylinder of the same radius. Skip it.
980 if (Abs(theRR - theRL) > aTolConf) {
981 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
984 if (theTransLenL > aTolConf) {
985 // 4.1. Construct the internal surface of right transition pipe.
986 gp_Pnt aPRight (theLen1, 0., 0.);
987 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
988 TopoDS_Shape aConeRight =
989 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
991 if (aConeRight.IsNull() == Standard_False) {
992 aConicalFaces.Append(aConeRight);
997 // 5. Construct the internal surface of incident reduction pipe.
998 if (theRI > aTolConf) {
999 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1001 if (theTransLenI > aTolConf) {
1002 // 5.1. Construct the internal surface of incident transition pipe.
1003 gp_Pnt aPInci (0., 0., theLen2);
1004 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1005 TopoDS_Shape aConeInci =
1006 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1008 if (aConeInci.IsNull() == Standard_False) {
1009 aConicalFaces.Append(aConeInci);
1014 // Get faces that are laying on cylindrical surfaces.
1015 TopTools_ListOfShape aFaces;
1016 gp_Trsf anInvTrsf = theTrsf.Inverted();
1018 for (i = 0; i < aMaxNbSurf; i++) {
1019 if (aSurface[i].IsNull()) {
1023 aSurface[i]->Transform(theTrsf);
1025 TopTools_ListOfShape aLocalFaces;
1027 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1032 // Check if the result contains outer cylinders.
1033 // It is required for main and incident pipes.
1034 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1036 while (anIter.More()) {
1037 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1038 Standard_Boolean isInside = Standard_False;
1040 // Get a vertex from this shape
1042 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1044 if (aVtx.IsNull() == Standard_False) {
1045 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1047 aPnt.Transform(anInvTrsf);
1050 // Check if the point is inside the main pipe.
1051 isInside = (Abs(aPnt.X()) <= theLen1);
1053 // Check if the point is inside the incident pipe.
1054 isInside = (aPnt.Z() <= theLen2);
1063 // Remove this face.
1064 aLocalFaces.Remove(anIter);
1069 aFaces.Append(aLocalFaces);
1072 // Get faces that are laying on conical faces.
1073 if (aConicalFaces.IsEmpty() == Standard_False) {
1074 Handle(GEOM_Object) aCone =
1075 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1076 Handle(GEOM_Function) aFunction =
1077 aCone->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1078 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1079 Handle(GEOM_Object) aConeFromShape;
1081 for (; aFIter.More(); aFIter.Next()) {
1082 aFunction->SetValue(aFIter.Value());
1083 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1085 if (aConeFromShape.IsNull() == Standard_False) {
1086 aConeFromShape->GetLastFunction()->SetDescription("");
1087 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1088 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1090 for (; anExp.More(); anExp.Next()) {
1091 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1093 if (aConeFace.IsNull() == Standard_False) {
1094 aFaces.Append(aConeFace);
1101 // Create a group of internal faces.
1102 if (aFaces.IsEmpty() == Standard_False) {
1103 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1105 if (aGroup.IsNull() == Standard_False) {
1106 aGroup->GetLastFunction()->SetDescription("");
1107 aGroup->SetName("INTERNAL_FACES");
1109 TopTools_IndexedMapOfShape anIndices;
1110 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1112 TopExp::MapShapes(aShape, anIndices);
1114 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1116 for (; anIter.More(); anIter.Next()) {
1117 const TopoDS_Shape &aFace = anIter.Value();
1118 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1121 aSeqIDs->Append(anIndex);
1125 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1126 aGroup->GetLastFunction()->SetDescription("");
1127 theSeq->Append(aGroup);
1136 bool GEOMImpl_IAdvancedOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1137 double theR1, double theW1, double theL1,
1138 double theR2, double theW2, double theL2,
1139 double theH, double theW,
1140 double theRF, bool isNormal)
1144 // Build tools for partition operation:
1145 // 1 face and 2 planes
1147 Handle(GEOM_Object) arete_intersect_int, arete_intersect_ext;
1148 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1149 Handle(GEOM_Object) chan_racc;
1150 Handle(GEOM_Object) vi1, vi2;
1151 Handle(GEOM_Object) Te3;
1155 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1156 Vector_Z->GetLastFunction()->SetDescription("");
1159 double aSize = 2*(theL1 + theL2);
1160 double aR1Ext = theR1 + theW1;
1161 double aR2Ext = theR2 + theW2;
1162 double theVertCylinderRadius = aR2Ext + theW + theRF;
1163 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1165 // Common edges on internal cylinder
1166 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1167 box_i->GetLastFunction()->SetDescription("");
1168 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1169 box_i->GetLastFunction()->SetDescription("");
1171 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1172 TCollection_AsciiString theDesc = aFunction->GetDescription();
1173 Handle(TColStd_HSequenceOfTransient) edges_i =
1174 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1175 // Recover previous description to get rid of Propagate dump
1176 aFunction->SetDescription(theDesc);
1177 if (edges_i.IsNull() || edges_i->Length() == 0) {
1178 SetErrorCode("Internal edges not found");
1181 for (int i=1; i<=edges_i->Length();i++) {
1182 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1183 anObj->GetLastFunction()->SetDescription("");
1185 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1187 // search for vertices located on both internal pipes
1188 aFunction = theShape->GetLastFunction();
1189 theDesc = aFunction->GetDescription();
1190 Handle(TColStd_HSequenceOfTransient) vertices_i =
1191 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1192 // Recover previous description to get rid of Propagate dump
1193 aFunction->SetDescription(theDesc);
1194 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1195 SetErrorCode("Internal vertices not found");
1199 double d1min = theR2+theW2, d2min=theR2+theW2;
1200 for (int i = 1; i <= vertices_i->Length(); i++) {
1201 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1202 v->GetLastFunction()->SetDescription("");
1203 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1204 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1205 if (Abs(aP.X()) <= Precision::Confusion()) {
1206 if (Abs(aP.Y()) < d1min) {
1208 d1min = Abs(aP.Y());
1210 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1211 if (Abs(aP.X()) < d2min) {
1213 d2min = Abs(aP.X());
1217 if (vi1.IsNull() || vi2.IsNull()) {
1218 SetErrorCode("Cannot find internal intersection vertices");
1222 std::list<Handle(GEOM_Object)> theShapes;
1225 Handle(GEOM_Object) ve1, ve2;
1226 TopoDS_Vertex vertex1, vertex2;
1228 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1229 box_e->GetLastFunction()->SetDescription("");
1230 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1231 box_e->GetLastFunction()->SetDescription("");
1233 // search for vertices located on both external pipes
1234 aFunction = theShape->GetLastFunction();
1235 theDesc = aFunction->GetDescription();
1236 Handle(TColStd_HSequenceOfTransient) vertices_e =
1237 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1238 // Recover previous description to get rid of Propagate dump
1239 aFunction->SetDescription(theDesc);
1240 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1241 SetErrorCode("External vertices not found");
1245 double d1max = 0, d2max = 0;
1246 for (int i = 1; i <= vertices_e->Length(); i++) {
1247 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1248 v->GetLastFunction()->SetDescription("");
1249 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1250 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1251 if (Abs(aP.X()) <= Precision::Confusion()) {
1252 if (Abs(aP.Y()) > d1max) {
1255 d1max = Abs(aP.Y());
1257 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1258 if (Abs(aP.X()) > d2max) {
1261 d2max = Abs(aP.X());
1265 if (ve1.IsNull() || ve2.IsNull()) {
1266 SetErrorCode("Cannot find external intersection vertices");
1269 Handle(GEOM_Object) edge_e1, edge_e2;
1271 // Common edges on external cylinder
1272 aFunction = theShape->GetLastFunction();
1273 theDesc = aFunction->GetDescription();
1274 Handle(TColStd_HSequenceOfTransient) edges_e =
1275 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1276 // Recover previous description to get rid of Propagate dump
1277 aFunction->SetDescription(theDesc);
1278 if (edges_e.IsNull() || edges_e->Length() == 0) {
1279 SetErrorCode("External edges not found");
1282 ShapeAnalysis_Edge sae;
1283 for (int i=1; i<=edges_e->Length();i++) {
1284 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1285 anObj->GetLastFunction()->SetDescription("");
1286 TopoDS_Edge anEdge = TopoDS::Edge(anObj->GetValue());
1287 if ( !anEdge.IsNull() &&
1288 (sae.FirstVertex(anEdge).IsSame(vertex1) || sae.LastVertex(anEdge).IsSame(vertex1)) &&
1289 (sae.FirstVertex(anEdge).IsSame(vertex2) || sae.LastVertex(anEdge).IsSame(vertex2))) {
1290 arete_intersect_ext = anObj;
1294 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1295 if (edge_e1.IsNull()) {
1296 SetErrorCode("Edge 1 could not be built");
1300 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1301 if (edge_e2.IsNull()) {
1302 SetErrorCode("Edge 2 could not be built");
1306 edge_e1->GetLastFunction()->SetDescription("");
1307 edge_e2->GetLastFunction()->SetDescription("");
1309 std::list<Handle(GEOM_Object)> edge_e_elist;
1310 edge_e_elist.push_back(arete_intersect_int);
1311 edge_e_elist.push_back(edge_e1);
1312 edge_e_elist.push_back(arete_intersect_ext);
1313 edge_e_elist.push_back(edge_e2);
1314 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1315 if (wire_t.IsNull()) {
1316 SetErrorCode("Impossible to build wire");
1319 wire_t->GetLastFunction()->SetDescription("");
1320 face_t = myShapesOperations->MakeFace(wire_t, false);
1321 if (face_t.IsNull()) {
1322 SetErrorCode("Impossible to build face");
1325 face_t->GetLastFunction()->SetDescription("");
1327 theShapes.push_back(theShape);
1328 theShapes.push_back(vi1);
1329 theShapes.push_back(vi2);
1330 theShapes.push_back(ve1);
1331 theShapes.push_back(ve2);
1332 theShapes.push_back(edge_e1);
1333 theShapes.push_back(edge_e2);
1334 theShapes.push_back(wire_t);
1335 theShapes.push_back(face_t);
1338 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1339 int idP1, idP2, idP3, idP4;
1342 std::vector<int> LX;
1343 std::vector<int> LY;
1344 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1345 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1346 box_e->GetLastFunction()->SetDescription("");
1347 box_e = myTransformOperations->TranslateDXDYDZ
1348 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1349 box_e->GetLastFunction()->SetDescription("");
1351 aFunction = theShape->GetLastFunction();
1352 theDesc = aFunction->GetDescription();
1353 Handle(TColStd_HSequenceOfTransient) extremVertices =
1354 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1355 // Recover previous description to get rid of Propagate dump
1356 aFunction->SetDescription(theDesc);
1358 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1360 SetErrorCode("Vertices on chamfer not found");
1362 SetErrorCode("Vertices on fillet not found");
1366 theShapes.push_back(theShape);
1367 theShapes.push_back(box_e);
1368 if (extremVertices->Length() != 6) {
1369 // for (int i=1; i<=extremVertices->Length(); i++){
1370 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1372 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1373 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1374 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1375 SetErrorCode("Bad number of vertices on chamfer found");
1379 for (int i=1; i<=extremVertices->Length(); i++){
1380 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1381 aV->GetLastFunction()->SetDescription("");
1382 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1384 if (Abs(aP.X()) <= Precision::Confusion()) {
1385 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1387 if (aP.Z()-ZX > Precision::Confusion()) {
1394 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1396 if (aP.Z() - ZY > Precision::Confusion()) {
1407 if (LX.at(0) == PZX)
1410 if (LY.at(0) == PZY)
1413 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1414 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1415 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1416 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1418 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1419 if (Cote_1.IsNull()) {
1420 SetErrorCode("Impossible to build edge in thickness");
1423 Cote_1->GetLastFunction()->SetDescription("");
1425 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1426 if (Cote_2.IsNull()) {
1427 SetErrorCode("Impossible to build edge in thickness");
1430 Cote_2->GetLastFunction()->SetDescription("");
1432 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1433 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1434 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1435 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1436 if (edge_chan_princ.IsNull()) {
1437 SetErrorCode("Impossible to find edge on main pipe");
1440 edge_chan_princ->GetLastFunction()->SetDescription("");
1442 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1443 if (edge_chan_inc.IsNull()) {
1444 SetErrorCode("Impossible to find edge on incident pipe");
1447 edge_chan_inc->GetLastFunction()->SetDescription("");
1449 std::list<Handle(GEOM_Object)> edgeList1;
1450 edgeList1.push_back(edge_chan_princ);
1451 edgeList1.push_back(Cote_1);
1452 edgeList1.push_back(arete_intersect_int);
1453 edgeList1.push_back(Cote_2);
1455 // std::cerr << "Creating wire 1" << std::endl;
1456 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1457 if (wire_t.IsNull()) {
1458 SetErrorCode("Impossible to build wire");
1461 wire_t->GetLastFunction()->SetDescription("");
1463 // std::cerr << "Creating face 1" << std::endl;
1464 face_t = myShapesOperations->MakeFace(wire_t, false);
1465 if (face_t.IsNull()) {
1466 SetErrorCode("Impossible to build face");
1469 face_t->GetLastFunction()->SetDescription("");
1470 theShapes.push_back(face_t);
1472 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1473 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1474 double deltaZ = aP2.Z() - aP5.Z();
1475 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1476 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1477 if (P5bis.IsNull()) {
1478 SetErrorCode("Impossible to translate vertex");
1481 P5bis->GetLastFunction()->SetDescription("");
1483 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1484 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1485 deltaZ = aP4.Z() - aP6.Z();
1486 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1487 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1488 if (P6bis.IsNull()) {
1489 SetErrorCode("Impossible to translate vertex");
1492 P6bis->GetLastFunction()->SetDescription("");
1494 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1495 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1496 if (Cote_3.IsNull()) {
1497 SetErrorCode("Impossible to build edge in thickness");
1500 Cote_3->GetLastFunction()->SetDescription("");
1502 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1503 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1504 if (Cote_4.IsNull()) {
1505 SetErrorCode("Impossible to build edge in thickness");
1508 Cote_4->GetLastFunction()->SetDescription("");
1510 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1511 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1512 if (Cote_4.IsNull()) {
1513 SetErrorCode("Impossible to build edge in thickness");
1516 Cote_5->GetLastFunction()->SetDescription("");
1518 //std::list<Handle(GEOM_Object)> edgeList2;
1519 //edgeList2.push_back(edge_chan_inc);
1520 //edgeList2.push_back(Cote_3);
1521 //edgeList2.push_back(Cote_5);
1522 //edgeList2.push_back(Cote_4);
1523 // std::cerr << "Creating wire 2" << std::endl;
1524 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1525 //if (wire_t2.IsNull()) {
1526 // SetErrorCode("Impossible to build wire");
1529 //wire_t2->GetLastFunction()->SetDescription("");
1530 // std::cerr << "Creating face 2" << std::endl;
1531 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1533 // Mantis issue 0021682
1534 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1535 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1536 if (face_t2.IsNull()) {
1537 SetErrorCode("Impossible to build face");
1540 face_t2->GetLastFunction()->SetDescription("");
1541 theShapes.push_back(face_t2);
1545 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1546 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1547 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1548 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1549 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1550 aP0->GetLastFunction()->SetDescription("");
1551 aVZ->GetLastFunction()->SetDescription("");
1552 aVXZ->GetLastFunction()->SetDescription("");
1553 aPlnOZ->GetLastFunction()->SetDescription("");
1554 aPlnOXZ->GetLastFunction()->SetDescription("");
1555 theShapes.push_back(aPlnOZ);
1556 theShapes.push_back(aPlnOXZ);
1559 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1560 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1561 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1562 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1563 Handle(TColStd_HArray1OfInteger) theMaterials;
1565 partitionShapes->Append(theShape);
1566 theTools->Append(aPlnOZ);
1567 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1568 theTools->Append(aPlnOXZ);
1569 theTools->Append(face_t);
1571 theTools->Append(face_t2);
1573 Te3 = myBooleanOperations->MakePartition
1574 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1575 TopAbs_SOLID, false, theMaterials, 0, false, Standard_False);
1577 SetErrorCode("Impossible to build partition of TShape");
1580 Te3->GetLastFunction()->SetDescription("");
1582 // Last verification: result should be a block
1583 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1584 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3,errList)) {
1585 SetErrorCode("TShape is not a compound of block");
1589 // // BEGIN Compound of created shapes - Only for debug purpose
1590 // theShapes.clear();
1591 // theShapes.push_back(theShape);
1592 // theShapes.push_back(aPlnOZ);
1593 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1594 // theShapes.push_back(aPlnOXZ);
1595 // theShapes.push_back(face_t);
1597 // theShapes.push_back(face_t2);
1599 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1600 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1601 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1602 // // END Compound of created shapes - Only for debug purpose
1604 TopoDS_Shape aShape = Te3->GetValue();
1605 theShape->GetLastFunction()->SetValue(aShape);
1607 catch (Standard_Failure) {
1608 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1609 SetErrorCode(aFail->GetMessageString());
1617 // Mirror and glue faces
1618 bool GEOMImpl_IAdvancedOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1619 double theR1, double theW1, double theL1,
1620 double theR2, double theW2, double theL2)
1625 double aSize = 2*(theL1 + theL2);
1626 double aR1Ext = theR1 + theW1;
1629 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1630 aP0->GetLastFunction()->SetDescription("");
1631 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1632 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1633 aVX->GetLastFunction()->SetDescription("");
1634 aVY->GetLastFunction()->SetDescription("");
1635 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1636 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1637 aPlane_OX->GetLastFunction()->SetDescription("");
1638 aPlane_OY->GetLastFunction()->SetDescription("");
1640 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1642 SetErrorCode("Impossible to build mirror of quarter TShape");
1646 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1648 SetErrorCode("Impossible to build mirror of half TShape");
1652 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1654 SetErrorCode("Impossible to build mirror of half TShape");
1658 std::list<Handle(GEOM_Object)> aShapesList;
1659 aShapesList.push_back(theShape);
1660 aShapesList.push_back(Te4);
1661 aShapesList.push_back(Te5);
1662 aShapesList.push_back(Te6);
1663 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1665 SetErrorCode("Impossible to build compound");
1669 // Copy source shape
1670 TopoDS_Shape aShapeCopy;
1671 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1672 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1674 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
1676 SetErrorCode("Impossible to glue faces of TShape");
1680 TopoDS_Shape aShape = Te8->GetValue();
1681 BRepCheck_Analyzer anAna (aShape, Standard_True);
1683 if (!anAna.IsValid()) {
1684 // Try to do gluing with the tolerance equal to maximal
1685 // tolerance of vertices of the source shape.
1686 Standard_Real aTolMax = -RealLast();
1688 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1689 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1690 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1692 if (aTol > aTolMax) {
1698 Te7->GetLastFunction()->SetValue(aShapeCopy);
1699 Te8 = myShapesOperations->MakeGlueFaces(Te7, aTolMax, true);
1702 SetErrorCode("Impossible to glue faces of TShape");
1706 aShape = Te8->GetValue();
1710 theShape->GetLastFunction()->SetValue(aShape);
1712 Te4->GetLastFunction()->SetDescription("");
1713 Te5->GetLastFunction()->SetDescription("");
1714 Te6->GetLastFunction()->SetDescription("");
1715 Te7->GetLastFunction()->SetDescription("");
1716 Te8->GetLastFunction()->SetDescription("");
1722 //=======================================================================
1723 //function : MakePipeTShapeThicknessReduction
1724 //purpose : Static method. Add thiskness reduction elements at the three
1725 // open ends of the T-Shape.
1726 //=======================================================================
1727 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakePipeTShapeThicknessReduction
1728 (TopoDS_Shape theShape,
1729 double r1, double w1, double l1,
1730 double r2, double w2, double l2,
1731 double rL, double wL, double ltransL, double lthinL,
1732 double rR, double wR, double ltransR, double lthinR,
1733 double rI, double wI, double ltransI, double lthinI,
1734 bool fuseReductions)
1736 // Add thickness reduction elements
1737 // at the three extremities: Left, Right and Incident
1739 // ---------------------.
1741 // ---------------------. \
1742 // ^ \ '-----------------.
1744 // | '-----------------'
1746 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1749 TopoDS_Shape aResult = theShape;
1750 double aTol = Precision::Confusion();
1752 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1754 // Left reduction (rL, wL, ltransL, lthinL)
1755 if (rL > aTol && wL > aTol && ltransL > aTol) {
1756 gp_Pnt aPLeft (-l1, 0, 0);
1757 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1758 TopoDS_Shape aReductionLeft = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1759 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1761 if (fuseReductions) {
1762 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1763 if (!fuseL.IsDone())
1764 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1765 aResult = fuseL.Shape();
1772 B.Add(C, aReductionLeft);
1778 if (rR > aTol && wR > aTol && ltransR > aTol) {
1779 gp_Pnt aPRight (l1, 0, 0);
1780 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1781 TopoDS_Shape aReductionRight = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1782 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1784 if (fuseReductions) {
1785 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1786 if (!fuseR.IsDone())
1787 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1788 aResult = fuseR.Shape();
1795 B.Add(C, aReductionRight);
1800 // Incident reduction
1801 if (rI > aTol && wI > aTol && ltransI > aTol) {
1802 gp_Pnt aPInci (0, 0, l2);
1803 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1804 TopoDS_Shape aReductionInci = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1805 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1807 if (fuseReductions) {
1808 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1809 if (!fuseInci.IsDone())
1810 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1811 aResult = fuseInci.Shape();
1818 B.Add(C, aReductionInci);
1823 // Get rid of extra compounds
1824 TopTools_ListOfShape listShapeRes;
1825 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1826 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1828 if (!fuseReductions && listShapeRes.Extent() > 1) {
1829 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1834 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1835 for (; itSub.More(); itSub.Next())
1836 B.Add(C, itSub.Value());
1839 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1845 //=======================================================================
1846 //function : MakeThicknessReduction
1847 //purpose : Static method. Create one thickness reduction element.
1848 //=======================================================================
1849 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1850 const double R, const double W,
1851 const double Rthin, const double Wthin,
1852 const double Ltrans, const double Lthin,
1855 double aTol = Precision::Confusion();
1856 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1857 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1859 bool isThinPart = (Lthin > aTol);
1864 // ^ \ '-----------------.
1866 // | '-----------------'
1868 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1871 double RExt = R + W;
1872 double RthinExt = Rthin + Wthin;
1874 gp_Dir aNormal = theAxes.Direction();
1875 gp_Dir anXDir = theAxes.XDirection();
1876 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1877 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1879 // Build the transition part
1880 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1881 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1884 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1885 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1886 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1888 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1889 TopoDS_Shape aReduction = cut1.Shape();
1891 // Build the thin part, if required
1892 TopoDS_Shape aThinPart;
1894 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1895 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1898 if (!CExt.IsDone() || !CInt.IsDone())
1899 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1900 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1902 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1903 aThinPart = cut2.Shape();
1909 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1910 if (!fuse1.IsDone())
1911 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1912 aReduction = fuse1.Shape();
1916 // Partition the reduction on blocks
1917 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1918 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1919 gp_Pln aPln1 (anAxesPln1);
1920 gp_Pln aPln2 (anAxesPln2);
1921 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1922 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1923 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1925 GEOMAlgo_Splitter PS;
1926 PS.AddArgument(aReduction);
1928 PS.AddArgument(aThinPart);
1931 PS.SetLimit(TopAbs_SOLID);
1934 aReduction = PS.Shape();
1940 //=============================================================================
1943 * \brief Create a T-shape object with specified caracteristics for the main and
1944 * the incident pipes (radius, width, half-length).
1945 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1946 * \param theR1 Internal radius of main pipe
1947 * \param theW1 Width of main pipe
1948 * \param theL1 Half-length of main pipe
1949 * \param theR2 Internal radius of incident pipe (R2 < R1)
1950 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1951 * \param theL2 Half-length of incident pipe
1952 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1953 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1955 //=============================================================================
1956 Handle(TColStd_HSequenceOfTransient)
1957 GEOMImpl_IAdvancedOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1958 double theR2, double theW2, double theL2,
1959 double theRL, double theWL, double theLtransL, double theLthinL,
1960 double theRR, double theWR, double theLtransR, double theLthinR,
1961 double theRI, double theWI, double theLtransI, double theLthinI,
1964 MESSAGE("GEOMImpl_IAdvancedOperations::MakePipeTShape");
1967 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1969 //Add a new shape function with parameters
1970 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1971 if (aFunction.IsNull()) return NULL;
1973 //Check if the function is set correctly
1974 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1976 GEOMImpl_IPipeTShape aData (aFunction);
1984 aData.SetHexMesh(theHexMesh);
1986 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1987 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1988 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1990 //Compute the resulting value
1993 if (!GetSolver()->ComputeFunction(aFunction)) {
1994 SetErrorCode("TShape driver failed");
1999 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2001 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2005 if (isTRL || isTRR || isTRI) {
2006 // Add thickness reduction elements
2007 // at the three extremities: Left, Right and Incident
2008 TopoDS_Shape aResShape =
2009 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2010 theRL, theWL, theLtransL, theLthinL,
2011 theRR, theWR, theLtransR, theLthinR,
2012 theRI, theWI, theLtransI, theLthinI,
2014 aFunction->SetValue(aResShape);
2017 catch (Standard_Failure) {
2018 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2019 SetErrorCode(aFail->GetMessageString());
2023 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2024 aSeq->Append(aShape);
2029 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2030 0., 0., 0., aSeq, gp_Trsf()))
2034 // Get internal group.
2035 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2036 theRR, theLtransR, theRI, theLtransI,
2041 catch (Standard_Failure) {
2042 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2043 SetErrorCode(aFail->GetMessageString());
2047 //Make a Python command
2048 TCollection_AsciiString anEntry, aListRes("[");
2049 // Iterate over the sequence aSeq
2050 Standard_Integer aNbGroups = aSeq->Length();
2051 Standard_Integer i = 1;
2052 for (; i <= aNbGroups; i++) {
2053 Handle(Standard_Transient) anItem = aSeq->Value(i);
2054 if (anItem.IsNull()) continue;
2055 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2056 if (aGroup.IsNull()) continue;
2057 //Make a Python command
2058 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2059 aListRes += anEntry + ", ";
2061 aListRes.Trunc(aListRes.Length() - 2);
2063 GEOM::TPythonDump pd (aFunction);
2065 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2066 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2067 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2070 // thickness reduction
2072 pd << ", theRL=" << theRL << ", theWL=" << theWL
2073 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2075 pd << ", theRR=" << theRR << ", theWR=" << theWR
2076 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2078 pd << ", theRI=" << theRI << ", theWI=" << theWI
2079 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2088 //=============================================================================
2090 * MakePipeTShapeWithPosition
2091 * Create a T-shape object with specified caracteristics for the main and
2092 * the incident pipes (radius, width, half-length).
2093 * The extremities of the main pipe are located on junctions points P1 and P2.
2094 * The extremity of the incident pipe is located on junction point P3.
2095 * \param theR1 Internal radius of main pipe
2096 * \param theW1 Width of main pipe
2097 * \param theL1 Half-length of main pipe
2098 * \param theR2 Internal radius of incident pipe (R2 < R1)
2099 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2100 * \param theL2 Half-length of incident pipe
2101 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2102 * \param theP1 1st junction point of main pipe
2103 * \param theP2 2nd junction point of main pipe
2104 * \param theP3 Junction point of incident pipe
2105 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2107 //=============================================================================
2108 Handle(TColStd_HSequenceOfTransient)
2109 GEOMImpl_IAdvancedOperations::MakePipeTShapeWithPosition
2110 (double theR1, double theW1, double theL1,
2111 double theR2, double theW2, double theL2,
2112 double theRL, double theWL, double theLtransL, double theLthinL,
2113 double theRR, double theWR, double theLtransR, double theLthinR,
2114 double theRI, double theWI, double theLtransI, double theLthinI,
2116 Handle(GEOM_Object) theP1,
2117 Handle(GEOM_Object) theP2,
2118 Handle(GEOM_Object) theP3)
2122 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2126 //Add a new shape function with parameters
2127 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2128 if (aFunction.IsNull()) return NULL;
2130 //Check if the function is set correctly
2131 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2133 // Check new position
2134 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2138 GEOMImpl_IPipeTShape aData(aFunction);
2146 aData.SetHexMesh(theHexMesh);
2148 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2149 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2150 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2152 //Compute the resulting value
2155 if (!GetSolver()->ComputeFunction(aFunction)) {
2156 SetErrorCode("TShape driver failed");
2161 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2163 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2167 if (isTRL || isTRR || isTRI) {
2168 // Add thickness reduction elements
2169 // at the three extremities: Left, Right and Incident
2170 TopoDS_Shape aResShape =
2171 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2172 theRL, theWL, theLtransL, theLthinL,
2173 theRR, theWR, theLtransR, theLthinR,
2174 theRI, theWI, theLtransI, theLthinI,
2176 aFunction->SetValue(aResShape);
2179 catch (Standard_Failure) {
2180 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2181 SetErrorCode(aFail->GetMessageString());
2185 TopoDS_Shape Te = aShape->GetValue();
2188 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2189 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2190 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2191 aFunction->SetValue(aTrsf_Shape);
2193 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2194 aSeq->Append(aShape);
2199 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2200 0., 0., 0., aSeq, aTrsf)) {
2205 // Get internal group.
2206 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2207 theRR, theLtransR, theRI, theLtransI,
2212 catch (Standard_Failure) {
2213 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2214 SetErrorCode(aFail->GetMessageString());
2218 //Make a Python command
2219 TCollection_AsciiString anEntry, aListRes("[");
2220 // Iterate over the sequence aSeq
2221 Standard_Integer aNbGroups = aSeq->Length();
2222 Standard_Integer i = 1;
2223 for (; i <= aNbGroups; i++) {
2224 Handle(Standard_Transient) anItem = aSeq->Value(i);
2225 if (anItem.IsNull()) continue;
2226 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2227 if (aGroup.IsNull()) continue;
2228 //Make a Python command
2229 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2230 aListRes += anEntry + ", ";
2232 aListRes.Trunc(aListRes.Length() - 2);
2234 GEOM::TPythonDump pd (aFunction);
2236 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2237 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2238 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2239 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2241 // thickness reduction
2243 pd << ", theRL=" << theRL << ", theWL=" << theWL
2244 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2246 pd << ", theRR=" << theRR << ", theWR=" << theWR
2247 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2249 pd << ", theRI=" << theRI << ", theWI=" << theWI
2250 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2259 //=============================================================================
2261 * MakePipeTShapeChamfer
2262 * Create a T-shape object with specified caracteristics for the main and
2263 * the incident pipes (radius, width, half-length). A chamfer is created
2264 * on the junction of the pipes.
2265 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2266 * \param theR1 Internal radius of main pipe
2267 * \param theW1 Width of main pipe
2268 * \param theL1 Half-length of main pipe
2269 * \param theR2 Internal radius of incident pipe (R2 < R1)
2270 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2271 * \param theL2 Half-length of incident pipe
2272 * \param theH Height of chamfer.
2273 * \param theW Width of chamfer.
2274 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2275 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2277 //=============================================================================
2278 Handle(TColStd_HSequenceOfTransient)
2279 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamfer
2280 (double theR1, double theW1, double theL1,
2281 double theR2, double theW2, double theL2,
2282 double theRL, double theWL, double theLtransL, double theLthinL,
2283 double theRR, double theWR, double theLtransR, double theLthinR,
2284 double theRI, double theWI, double theLtransI, double theLthinI,
2285 double theH, double theW,
2290 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2291 //Add a new shape function with parameters
2292 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2293 if (aFunction.IsNull()) return NULL;
2295 //Check if the function is set correctly
2296 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2298 GEOMImpl_IPipeTShape aData(aFunction);
2308 aData.SetHexMesh(theHexMesh);
2310 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2311 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2312 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2314 //Compute the resulting value
2317 if (!GetSolver()->ComputeFunction(aFunction)) {
2318 SetErrorCode("TShape driver failed");
2322 catch (Standard_Failure) {
2323 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2324 SetErrorCode(aFail->GetMessageString());
2329 TopoDS_Shape aShapeShape = aShape->GetValue();
2330 TopTools_IndexedMapOfShape anEdgesIndices;
2331 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2332 // Common edges on external cylinders
2333 Handle(GEOM_Object) box_e;
2335 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2338 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2340 box_e->GetLastFunction()->SetDescription("");
2341 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2342 box_e->GetLastFunction()->SetDescription("");
2344 Handle(TColStd_HSequenceOfInteger) edges_e =
2345 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2346 box_e->GetLastFunction()->SetDescription("");
2348 if (edges_e.IsNull() || edges_e->Length() == 0) {
2349 SetErrorCode("External edges not found");
2352 int nbEdgesInChamfer = 0;
2353 std::list<int> theEdges;
2354 for (int i=1; i<=edges_e->Length();i++) {
2355 int edgeID = edges_e->Value(i);
2356 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2357 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2361 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2362 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2363 nbEdgesInChamfer ++;
2364 theEdges.push_back(edgeID);
2368 if (theHexMesh && nbEdgesInChamfer == 1)
2371 Handle(GEOM_Object) aChamfer;
2373 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2375 catch (Standard_Failure) {
2376 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2377 SetErrorCode(aFail->GetMessageString());
2380 if (aChamfer.IsNull()) {
2381 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2384 aChamfer->GetLastFunction()->SetDescription("");
2386 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2387 aFunction->SetValue(aChamferShape);
2391 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2393 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2397 // Add thickness reduction elements
2398 // at the three extremities: Left, Right and Incident
2401 if (isTRL || isTRR || isTRI) {
2402 TopoDS_Shape aResShape =
2403 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2404 theRL, theWL, theLtransL, theLthinL,
2405 theRR, theWR, theLtransR, theLthinR,
2406 theRI, theWI, theLtransI, theLthinI,
2408 aFunction->SetValue(aResShape);
2411 catch (Standard_Failure) {
2412 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2413 SetErrorCode(aFail->GetMessageString());
2417 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2418 aSeq->Append(aShape);
2423 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2424 theH, theW, 0., aSeq, gp_Trsf()))
2428 // Get internal group.
2429 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2430 theRR, theLtransR, theRI, theLtransI,
2435 catch (Standard_Failure) {
2436 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2437 SetErrorCode(aFail->GetMessageString());
2441 //Make a Python command
2442 TCollection_AsciiString anEntry, aListRes("[");
2443 // Iterate over the sequence aSeq
2444 Standard_Integer aNbGroups = aSeq->Length();
2445 Standard_Integer i = 1;
2446 for (; i <= aNbGroups; i++) {
2447 Handle(Standard_Transient) anItem = aSeq->Value(i);
2448 if (anItem.IsNull()) continue;
2449 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2450 if (aGroup.IsNull()) continue;
2451 //Make a Python command
2452 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2453 aListRes += anEntry + ", ";
2455 aListRes.Trunc(aListRes.Length() - 2);
2457 GEOM::TPythonDump pd (aFunction);
2459 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2460 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2461 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2462 << theH << ", " << theW << ", " << theHexMesh;
2464 // thickness reduction
2466 pd << ", theRL=" << theRL << ", theWL=" << theWL
2467 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2469 pd << ", theRR=" << theRR << ", theWR=" << theWR
2470 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2472 pd << ", theRI=" << theRI << ", theWI=" << theWI
2473 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2482 //=============================================================================
2484 * MakePipeTShapeChamferWithPosition
2485 * Create a T-shape object with specified caracteristics for the main and
2486 * the incident pipes (radius, width, half-length). A chamfer is created
2487 * on the junction of the pipes.
2488 * The extremities of the main pipe are located on junctions points P1 and P2.
2489 * The extremity of the incident pipe is located on junction point P3.
2490 * \param theR1 Internal radius of main pipe
2491 * \param theW1 Width of main pipe
2492 * \param theL1 Half-length of main pipe
2493 * \param theR2 Internal radius of incident pipe (R2 < R1)
2494 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2495 * \param theL2 Half-length of incident pipe
2496 * \param theH Height of chamfer.
2497 * \param theW Width of chamfer.
2498 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2499 * \param theP1 1st junction point of main pipe
2500 * \param theP2 2nd junction point of main pipe
2501 * \param theP3 Junction point of incident pipe
2502 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2504 //=============================================================================
2505 Handle(TColStd_HSequenceOfTransient)
2506 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamferWithPosition
2507 (double theR1, double theW1, double theL1,
2508 double theR2, double theW2, double theL2,
2509 double theRL, double theWL, double theLtransL, double theLthinL,
2510 double theRR, double theWR, double theLtransR, double theLthinR,
2511 double theRI, double theWI, double theLtransI, double theLthinI,
2512 double theH, double theW,
2514 Handle(GEOM_Object) theP1,
2515 Handle(GEOM_Object) theP2,
2516 Handle(GEOM_Object) theP3)
2520 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2521 //Add a new shape function with parameters
2522 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2523 if (aFunction.IsNull()) return NULL;
2525 //Check if the function is set correctly
2526 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2528 // Check new position
2529 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2533 GEOMImpl_IPipeTShape aData(aFunction);
2543 aData.SetHexMesh(theHexMesh);
2545 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2546 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2547 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2549 //Compute the resulting value
2552 if (!GetSolver()->ComputeFunction(aFunction)) {
2553 SetErrorCode("TShape driver failed");
2557 catch (Standard_Failure) {
2558 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2559 SetErrorCode(aFail->GetMessageString());
2564 TopoDS_Shape aShapeShape = aShape->GetValue();
2565 TopTools_IndexedMapOfShape anEdgesIndices;
2566 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2567 // Common edges on external cylinders
2568 Handle(GEOM_Object) box_e;
2570 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2573 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2575 box_e->GetLastFunction()->SetDescription("");
2576 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2577 box_e->GetLastFunction()->SetDescription("");
2579 Handle(TColStd_HSequenceOfInteger) edges_e =
2580 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2581 box_e->GetLastFunction()->SetDescription("");
2583 if (edges_e.IsNull() || edges_e->Length() == 0) {
2584 SetErrorCode("External edges not found");
2587 int nbEdgesInChamfer = 0;
2588 std::list<int> theEdges;
2589 for (int i=1; i<=edges_e->Length();i++) {
2590 int edgeID = edges_e->Value(i);
2591 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2592 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2594 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2595 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2596 nbEdgesInChamfer ++;
2597 theEdges.push_back(edgeID);
2601 if (theHexMesh && nbEdgesInChamfer == 1)
2604 Handle(GEOM_Object) aChamfer;
2606 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2608 catch (Standard_Failure) {
2609 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2610 SetErrorCode(aFail->GetMessageString());
2613 if (aChamfer.IsNull()) {
2614 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2617 aChamfer->GetLastFunction()->SetDescription("");
2619 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2620 aFunction->SetValue(aChamferShape);
2624 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2626 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2630 // Add thickness reduction elements
2631 // at the three extremities: Left, Right and Incident
2634 if (isTRL || isTRR || isTRI) {
2635 TopoDS_Shape aResShape =
2636 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2637 theRL, theWL, theLtransL, theLthinL,
2638 theRR, theWR, theLtransR, theLthinR,
2639 theRI, theWI, theLtransI, theLthinI,
2641 aFunction->SetValue(aResShape);
2644 catch (Standard_Failure) {
2645 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2646 SetErrorCode(aFail->GetMessageString());
2651 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2652 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2653 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2654 aFunction->SetValue(aTrsf_Shape);
2656 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2657 aSeq->Append(aShape);
2662 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2663 theH, theW, 0., aSeq, aTrsf))
2667 // Get internal group.
2668 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2669 theRR, theLtransR, theRI, theLtransI,
2674 catch (Standard_Failure) {
2675 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2676 SetErrorCode(aFail->GetMessageString());
2680 //Make a Python command
2681 TCollection_AsciiString anEntry, aListRes("[");
2682 // Iterate over the sequence aSeq
2683 Standard_Integer aNbGroups = aSeq->Length();
2684 Standard_Integer i = 1;
2685 for (; i <= aNbGroups; i++) {
2686 Handle(Standard_Transient) anItem = aSeq->Value(i);
2687 if (anItem.IsNull()) continue;
2688 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2689 if (aGroup.IsNull()) continue;
2690 //Make a Python command
2691 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2692 aListRes += anEntry + ", ";
2694 aListRes.Trunc(aListRes.Length() - 2);
2696 GEOM::TPythonDump pd (aFunction);
2698 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2699 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2700 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2701 << theH << ", " << theW << ", " << theHexMesh << ", "
2702 << theP1 << ", " << theP2 << ", " << theP3;
2704 // thickness reduction
2706 pd << ", theRL=" << theRL << ", theWL=" << theWL
2707 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2709 pd << ", theRR=" << theRR << ", theWR=" << theWR
2710 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2712 pd << ", theRI=" << theRI << ", theWI=" << theWI
2713 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2722 //=============================================================================
2724 * MakePipeTShapeFillet
2725 * Create a T-shape object with specified caracteristics for the main and
2726 * the incident pipes (radius, width, half-length). A fillet is created
2727 * on the junction of the pipes.
2728 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2729 * \param theR1 Internal radius of main pipe
2730 * \param theW1 Width of main pipe
2731 * \param theL1 Half-length of main pipe
2732 * \param theR2 Internal radius of incident pipe (R2 < R1)
2733 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2734 * \param theL2 Half-length of incident pipe
2735 * \param theRF Radius of curvature of fillet.
2736 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2737 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2739 //=============================================================================
2740 Handle(TColStd_HSequenceOfTransient)
2741 GEOMImpl_IAdvancedOperations::MakePipeTShapeFillet
2742 (double theR1, double theW1, double theL1,
2743 double theR2, double theW2, double theL2,
2744 double theRL, double theWL, double theLtransL, double theLthinL,
2745 double theRR, double theWR, double theLtransR, double theLthinR,
2746 double theRI, double theWI, double theLtransI, double theLthinI,
2747 double theRF, bool theHexMesh)
2751 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2752 //Add a new shape function with parameters
2753 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2754 if (aFunction.IsNull()) return NULL;
2756 //Check if the function is set correctly
2757 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2759 GEOMImpl_IPipeTShape aData(aFunction);
2768 aData.SetHexMesh(theHexMesh);
2770 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2771 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2772 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2774 //Compute the resulting value
2777 if (!GetSolver()->ComputeFunction(aFunction)) {
2778 SetErrorCode("TShape driver failed");
2782 catch (Standard_Failure) {
2783 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2784 SetErrorCode(aFail->GetMessageString());
2789 TopoDS_Shape aShapeShape = aShape->GetValue();
2790 TopTools_IndexedMapOfShape anEdgesIndices;
2791 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2792 // Common edges on external cylinders
2793 Handle(GEOM_Object) box_e;
2795 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2798 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2800 box_e->GetLastFunction()->SetDescription("");
2801 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2802 box_e->GetLastFunction()->SetDescription("");
2804 Handle(TColStd_HSequenceOfInteger) edges_e =
2805 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2806 box_e->GetLastFunction()->SetDescription("");
2808 if (edges_e.IsNull() || edges_e->Length() == 0) {
2809 SetErrorCode("External edges not found");
2812 int nbEdgesInFillet = 0;
2813 std::list<int> theEdges;
2814 for (int i=1; i<=edges_e->Length();i++) {
2815 int edgeID = edges_e->Value(i);
2816 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2817 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2819 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2820 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2822 theEdges.push_back(edgeID);
2826 if (theHexMesh && nbEdgesInFillet == 1)
2830 Handle(GEOM_Object) aFillet;
2832 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2834 catch (Standard_Failure) {
2835 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2836 SetErrorCode(aFail->GetMessageString());
2839 if (aFillet.IsNull()) {
2840 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2841 SetErrorCode(myLocalOperations->GetErrorCode());
2844 aFillet->GetLastFunction()->SetDescription("");
2846 TopoDS_Shape aFilletShape = aFillet->GetValue();
2847 aFunction->SetValue(aFilletShape);
2850 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2851 // the following block, when enabled, leads to partitioning problems
2853 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2854 // BEGIN: Limit tolerances (debug)
2855 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2856 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2857 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2858 aCorr1->GetLastFunction()->SetDescription("");
2859 // END: Limit tolerances (debug)
2860 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2862 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2865 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2867 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2871 // Add thickness reduction elements
2872 // at the three extremities: Left, Right and Incident
2875 if (isTRL || isTRR || isTRI) {
2876 TopoDS_Shape aResShape =
2877 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2878 theRL, theWL, theLtransL, theLthinL,
2879 theRR, theWR, theLtransR, theLthinR,
2880 theRI, theWI, theLtransI, theLthinI,
2882 aFunction->SetValue(aResShape);
2885 catch (Standard_Failure) {
2886 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2887 SetErrorCode(aFail->GetMessageString());
2891 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2892 aSeq->Append(aShape);
2897 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2898 0., 0., theRF, aSeq, gp_Trsf()))
2902 // Get internal group.
2903 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2904 theRR, theLtransR, theRI, theLtransI,
2909 catch (Standard_Failure) {
2910 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2911 SetErrorCode(aFail->GetMessageString());
2915 //Make a Python command
2916 TCollection_AsciiString anEntry, aListRes("[");
2917 // Iterate over the sequence aSeq
2918 Standard_Integer aNbGroups = aSeq->Length();
2919 Standard_Integer i = 1;
2920 for (; i <= aNbGroups; i++) {
2921 Handle(Standard_Transient) anItem = aSeq->Value(i);
2922 if (anItem.IsNull()) continue;
2923 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2924 if (aGroup.IsNull()) continue;
2925 //Make a Python command
2926 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2927 aListRes += anEntry + ", ";
2929 aListRes.Trunc(aListRes.Length() - 2);
2931 GEOM::TPythonDump pd (aFunction);
2933 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2934 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2935 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2936 << theRF << ", " << theHexMesh;
2938 // thickness reduction
2940 pd << ", theRL=" << theRL << ", theWL=" << theWL
2941 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2943 pd << ", theRR=" << theRR << ", theWR=" << theWR
2944 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2946 pd << ", theRI=" << theRI << ", theWI=" << theWI
2947 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2956 //=============================================================================
2958 * MakePipeTShapeFilletWithPosition
2959 * \brief Create a T-shape object with specified caracteristics for the main and
2960 * the incident pipes (radius, width, half-length). A fillet is created
2961 * on the junction of the pipes.
2962 * The extremities of the main pipe are located on junctions points P1 and P2.
2963 * The extremity of the incident pipe is located on junction point P3.
2964 * \param theR1 Internal radius of main pipe
2965 * \param theW1 Width of main pipe
2966 * \param theL1 Half-length of main pipe
2967 * \param theR2 Internal radius of incident pipe (R2 < R1)
2968 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2969 * \param theL2 Half-length of incident pipe
2970 * \param theRF Radius of curvature of fillet
2971 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2972 * \param theP1 1st junction point of main pipe
2973 * \param theP2 2nd junction point of main pipe
2974 * \param theP3 Junction point of incident pipe
2975 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2977 //=============================================================================
2978 Handle(TColStd_HSequenceOfTransient)
2979 GEOMImpl_IAdvancedOperations::MakePipeTShapeFilletWithPosition
2980 (double theR1, double theW1, double theL1,
2981 double theR2, double theW2, double theL2,
2982 double theRL, double theWL, double theLtransL, double theLthinL,
2983 double theRR, double theWR, double theLtransR, double theLthinR,
2984 double theRI, double theWI, double theLtransI, double theLthinI,
2985 double theRF, bool theHexMesh,
2986 Handle(GEOM_Object) theP1,
2987 Handle(GEOM_Object) theP2,
2988 Handle(GEOM_Object) theP3)
2992 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2993 //Add a new shape function with parameters
2994 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2995 if (aFunction.IsNull()) return NULL;
2997 //Check if the function is set correctly
2998 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
3000 // Check new position
3001 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
3005 GEOMImpl_IPipeTShape aData(aFunction);
3014 aData.SetHexMesh(theHexMesh);
3016 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
3017 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
3018 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
3020 //Compute the resulting value
3023 if (!GetSolver()->ComputeFunction(aFunction)) {
3024 SetErrorCode("TShape driver failed");
3028 catch (Standard_Failure) {
3029 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3030 SetErrorCode(aFail->GetMessageString());
3035 TopoDS_Shape aShapeShape = aShape->GetValue();
3036 TopTools_IndexedMapOfShape anEdgesIndices;
3037 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3038 // Common edges on external cylinders
3039 Handle(GEOM_Object) box_e;
3041 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3044 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3046 box_e->GetLastFunction()->SetDescription("");
3047 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3048 box_e->GetLastFunction()->SetDescription("");
3050 Handle(TColStd_HSequenceOfInteger) edges_e =
3051 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3052 box_e->GetLastFunction()->SetDescription("");
3054 if (edges_e.IsNull() || edges_e->Length() == 0) {
3055 SetErrorCode("External edges not found");
3058 int nbEdgesInFillet = 0;
3059 std::list<int> theEdges;
3060 for (int i=1; i<=edges_e->Length();i++) {
3061 int edgeID = edges_e->Value(i);
3062 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3063 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3065 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3066 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3068 theEdges.push_back(edgeID);
3072 if (theHexMesh && nbEdgesInFillet == 1)
3076 Handle(GEOM_Object) aFillet;
3078 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3080 catch (Standard_Failure) {
3081 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3082 SetErrorCode(aFail->GetMessageString());
3085 if (aFillet.IsNull()) {
3086 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3089 aFillet->GetLastFunction()->SetDescription("");
3091 TopoDS_Shape aFilletShape = aFillet->GetValue();
3092 aFunction->SetValue(aFilletShape);
3095 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3096 // the following block, when enabled, leads to partitioning problems
3098 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3099 // BEGIN: Limit tolerances (debug)
3100 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3101 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3102 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3103 aCorr1->GetLastFunction()->SetDescription("");
3104 // END: Limit tolerances (debug)
3105 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3107 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3110 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3112 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3116 // Add thickness reduction elements
3117 // at the three extremities: Left, Right and Incident
3120 if (isTRL || isTRR || isTRI) {
3121 TopoDS_Shape aResShape =
3122 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3123 theRL, theWL, theLtransL, theLthinL,
3124 theRR, theWR, theLtransR, theLthinR,
3125 theRI, theWI, theLtransI, theLthinI,
3127 aFunction->SetValue(aResShape);
3130 catch (Standard_Failure) {
3131 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3132 SetErrorCode(aFail->GetMessageString());
3137 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3138 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3139 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3140 aFunction->SetValue(aTrsf_Shape);
3142 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3143 aSeq->Append(aShape);
3148 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3149 0., 0., theRF, aSeq, aTrsf))
3153 // Get internal group.
3154 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3155 theRR, theLtransR, theRI, theLtransI,
3160 catch (Standard_Failure) {
3161 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3162 SetErrorCode(aFail->GetMessageString());
3166 //Make a Python command
3167 TCollection_AsciiString anEntry, aListRes("[");
3168 // Iterate over the sequence aSeq
3169 Standard_Integer aNbGroups = aSeq->Length();
3170 Standard_Integer i = 1;
3171 for (; i <= aNbGroups; i++) {
3172 Handle(Standard_Transient) anItem = aSeq->Value(i);
3173 if (anItem.IsNull()) continue;
3174 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3175 if (aGroup.IsNull()) continue;
3176 //Make a Python command
3177 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3178 aListRes += anEntry + ", ";
3180 aListRes.Trunc(aListRes.Length() - 2);
3182 GEOM::TPythonDump pd (aFunction);
3184 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3185 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3186 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3187 << theRF << ", " << theHexMesh << ", "
3188 << theP1 << ", " << theP2 << ", " << theP3;
3190 // thickness reduction
3192 pd << ", theRL=" << theRL << ", theWL=" << theWL
3193 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3195 pd << ", theRR=" << theRR << ", theWR=" << theWR
3196 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3198 pd << ", theRI=" << theRI << ", theWI=" << theWI
3199 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3208 //=============================================================================
3210 * This function allows to create a disk already divided into blocks. It can be
3211 * used to create divided pipes for later meshing in hexaedra.
3212 * \param theR Radius of the disk
3213 * \param theRatio Relative size of the central square diagonal against the disk diameter
3214 * \param theOrientation Plane on which the disk will be built
3215 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3216 * \return New GEOM_Object, containing the created shape.
3218 //=============================================================================
3219 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedDisk (double theR, double theRatio,
3220 int theOrientation, int thePattern)
3224 if (theOrientation != 1 &&
3225 theOrientation != 2 &&
3226 theOrientation != 3)
3228 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3232 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3234 //Add a new shape function with parameters
3235 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3236 if (aFunction.IsNull()) return NULL;
3238 //Check if the function is set correctly
3239 if (aFunction->GetDriverGUID() != GEOMImpl_DividedDiskDriver::GetID()) return NULL;
3241 GEOMImpl_IDividedDisk aData (aFunction);
3244 aData.SetRatio(theRatio);
3245 aData.SetOrientation(theOrientation);
3246 aData.SetType(thePattern);
3248 //Compute the resulting value
3250 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3253 if (!GetSolver()->ComputeFunction(aFunction)) {
3254 SetErrorCode("DividedDisk driver failed");
3258 catch (Standard_Failure) {
3259 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3260 SetErrorCode(aFail->GetMessageString());
3264 std::string aPatternStr;
3269 aPatternStr = "GEOM.SQUARE";
3272 aPatternStr = "GEOM.HEXAGON";
3276 //Make a Python command
3277 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3284 //=============================================================================
3286 * This function allows to create a disk already divided into blocks. It can be
3287 * used to create divided pipes for later meshing in hexaedra.
3288 * \param theR Radius of the disk
3289 * \param theRatio Relative size of the central square diagonal against the disk diameter
3290 * \return New GEOM_Object, containing the created shape.
3292 //=============================================================================
3293 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3294 Handle(GEOM_Object) theVec,
3302 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3304 //Add a new shape function with parameters
3305 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3306 if (aFunction.IsNull()) return NULL;
3308 //Check if the function is set correctly
3309 if (aFunction->GetDriverGUID() != GEOMImpl_DividedDiskDriver::GetID()) return NULL;
3311 GEOMImpl_IDividedDisk aData (aFunction);
3313 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3314 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3316 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3318 aData.SetCenter(aRefPnt);
3319 aData.SetVector(aRefVec);
3322 aData.SetRatio(theRatio);
3323 aData.SetType(thePattern);
3325 //Compute the resulting value
3327 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3330 if (!GetSolver()->ComputeFunction(aFunction)) {
3331 SetErrorCode("DividedDisk driver failed");
3335 catch (Standard_Failure) {
3336 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3337 SetErrorCode(aFail->GetMessageString());
3341 std::string aPatternStr;
3346 aPatternStr = "GEOM.SQUARE";
3349 aPatternStr = "GEOM.HEXAGON";
3354 //Make a Python command
3355 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3362 //=============================================================================
3364 * Builds a cylinder prepared for hexa meshes
3365 * \param theR Radius of the cylinder
3366 * \param theH Height of the cylinder
3367 * \return New GEOM_Object, containing the created shape.
3369 //=============================================================================
3370 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedCylinder (double theR,
3377 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3379 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3380 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3382 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3384 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3385 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3386 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3388 std::string aPatternStr;
3393 aPatternStr = "GEOM.SQUARE";
3396 aPatternStr = "GEOM.HEXAGON";
3400 //Make a Python command
3401 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3407 //=============================================================================
3409 * Create a smoothing surface from a set of points
3410 * \param thelPoints list of points or compounds of points
3411 * \param theNbMax maximum number of Bezier pieces in the resulting surface.
3412 * \param theDegMax maximum degree of the resulting BSpline surface
3413 * \param theDMax specifies maximum value of the GeomPlate_PlateG0Criterion criterion.
3414 * \return New GEOM_Object, containing the created shape.
3416 //=============================================================================
3417 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints,
3425 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3427 //Add a new shape function with parameters
3428 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3429 if (aFunction.IsNull()) return NULL;
3431 //Check if the function is set correctly
3432 if (aFunction->GetDriverGUID() != GEOMImpl_SmoothingSurfaceDriver::GetID()) return NULL;
3434 GEOMImpl_ISmoothingSurface aData (aFunction);
3436 int aLen = thelPoints.size();
3437 aData.SetLength(aLen);
3439 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3440 for (; it != thelPoints.end(); it++, ind++) {
3441 Handle(GEOM_Function) aRefObj = (*it)->GetLastFunction();
3442 if (aRefObj.IsNull()) {
3443 SetErrorCode("NULL point or compound for bSplineFaceShape");
3446 aData.SetPntOrComp(ind, aRefObj);
3449 aData.SetNbMax(theNbMax);
3450 aData.SetDegMax(theDegMax);
3451 aData.SetDMax(theDMax);
3453 //Compute the resulting value
3455 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3458 if (!GetSolver()->ComputeFunction(aFunction)) {
3459 SetErrorCode("SmoothingSurface driver failed");
3463 catch (Standard_Failure) {
3464 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3465 SetErrorCode(aFail->GetMessageString());
3469 //Make a Python command
3470 GEOM::TPythonDump pd (aFunction);
3471 pd << aShape << " = geompy.MakeSmoothingSurface([";
3472 it = thelPoints.begin();
3474 while (it != thelPoints.end()) {
3475 pd << ", " << (*it++);
3479 << theDegMax << ", "
3486 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/