1 // Copyright (C) 2007-2013 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.
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"
35 #include "GEOMImpl_Gen.hxx"
36 #include "GEOMImpl_Types.hxx"
38 #include "GEOMImpl_IBasicOperations.hxx"
39 #include "GEOMImpl_IBooleanOperations.hxx"
40 #include "GEOMImpl_IShapesOperations.hxx"
41 #include "GEOMImpl_ITransformOperations.hxx"
42 #include "GEOMImpl_IBlocksOperations.hxx"
43 #include "GEOMImpl_I3DPrimOperations.hxx"
44 #include "GEOMImpl_ILocalOperations.hxx"
45 #include "GEOMImpl_IHealingOperations.hxx"
47 #include "GEOMImpl_GlueDriver.hxx"
48 #include "GEOMImpl_PipeTShapeDriver.hxx"
49 #include "GEOMImpl_IPipeTShape.hxx"
50 #include "GEOMImpl_DividedDiskDriver.hxx"
51 #include "GEOMImpl_IDividedDisk.hxx"
52 // #include "GEOMImpl_DividedCylinderDriver.hxx"
53 // #include "GEOMImpl_IDividedCylinder.hxx"
54 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/
56 #include <TDF_Tool.hxx>
57 #include <TFunction_DriverTable.hxx>
58 #include <TFunction_Driver.hxx>
59 #include <TFunction_Logbook.hxx>
60 #include <TNaming_CopyShape.hxx>
63 #include <TopExp_Explorer.hxx>
65 #include <TopoDS_Vertex.hxx>
66 #include <TopTools_IndexedMapOfShape.hxx>
67 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
70 #include <BRep_Builder.hxx>
71 #include <BRep_Tool.hxx>
73 #include <BRepAlgoAPI_Cut.hxx>
74 #include <BRepAlgoAPI_Fuse.hxx>
75 #include <BRepBuilderAPI_MakeFace.hxx>
76 #include <BRepBuilderAPI_MakeVertex.hxx>
77 #include <BRepBuilderAPI_Transform.hxx>
78 #include <BRepPrimAPI_MakeCone.hxx>
79 #include <BRepPrimAPI_MakeCylinder.hxx>
88 #include <Standard_Stream.hxx>
89 #include <Standard_Failure.hxx>
90 #include <StdFail_NotDone.hxx>
91 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
93 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
94 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
95 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
96 #define THICKNESS "Thickness" //"Epaisseur"
97 #define FLANGE "Flange" // "Collerette"
98 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
99 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
100 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
101 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
103 #define FIND_GROUPS_BY_POINTS 1
105 //=============================================================================
109 //=============================================================================
110 GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations(GEOM_Engine* theEngine, int theDocID) :
111 GEOM_IOperations(theEngine, theDocID)
113 MESSAGE("GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations");
114 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
115 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
116 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
117 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
118 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
119 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
120 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
121 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
124 //=============================================================================
128 //=============================================================================
129 GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations()
131 MESSAGE("GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations");
132 delete myBasicOperations;
133 delete myBooleanOperations;
134 delete myShapesOperations;
135 delete myTransformOperations;
136 delete myBlocksOperations;
137 delete my3DPrimOperations;
138 delete myLocalOperations;
139 delete myHealingOperations;
142 //=============================================================================
146 //=============================================================================
147 gp_Trsf GEOMImpl_IAdvancedOperations::GetPositionTrsf(double theL1, double theL2,
148 Handle(GEOM_Object) theP1,
149 Handle(GEOM_Object) theP2,
150 Handle(GEOM_Object) theP3)
152 // Old Local Coordinates System oldLCS
154 gp_Pnt P1(-theL1, 0, 0);
155 gp_Pnt P2(theL1, 0, 0);
156 gp_Pnt P3(0, 0, theL2);
158 gp_Dir oldX(gp_Vec(P1, P2));
159 gp_Dir oldZ(gp_Vec(P0, P3));
160 gp_Ax3 oldLCS(P0, oldZ, oldX);
162 // New Local Coordinates System newLCS
163 double LocX, LocY, LocZ;
164 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
165 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
166 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
167 LocX = (newP1.X() + newP2.X()) / 2.;
168 LocY = (newP1.Y() + newP2.Y()) / 2.;
169 LocZ = (newP1.Z() + newP2.Z()) / 2.;
170 gp_Pnt newO(LocX, LocY, LocZ);
172 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
173 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
174 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
177 aTrsf.SetDisplacement(oldLCS, newLCS);
182 //=============================================================================
184 * CheckCompatiblePosition
187 //=============================================================================
188 bool GEOMImpl_IAdvancedOperations::CheckCompatiblePosition(double& theL1, double& theL2,
189 Handle(GEOM_Object) theP1,
190 Handle(GEOM_Object) theP2,
191 Handle(GEOM_Object) theP3,
195 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
196 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
197 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
199 double d12 = P1.Distance(P2);
200 double d13 = P1.Distance(P3);
201 double d23 = P2.Distance(P3);
202 // double d2 = newO.Distance(P3);
204 if (Abs(d12) <= Precision::Confusion()) {
205 SetErrorCode("Junctions points P1 and P2 are identical");
208 if (Abs(d13) <= Precision::Confusion()) {
209 SetErrorCode("Junctions points P1 and P3 are identical");
212 if (Abs(d23) <= Precision::Confusion()) {
213 SetErrorCode("Junctions points P2 and P3 are identical");
218 double newL1 = 0.5 * d12;
219 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
221 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
223 if (fabs(newL1 - theL1) > Precision::Approximation()) {
224 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
225 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
226 // std::cerr << "theL1 = newL1" << std::endl;
230 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
236 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
238 if (fabs(newL2 - theL2) > Precision::Approximation()) {
239 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
240 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
244 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
254 //=============================================================================
256 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
258 //=============================================================================
259 bool GEOMImpl_IAdvancedOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
260 double theR1, double theW1, double theL1,
261 double theR2, double theW2, double theL2,
262 double theH, double theW, double theRF,
263 Handle(TColStd_HSequenceOfTransient) theSeq,
268 if (theShape.IsNull()) return false;
270 TopoDS_Shape aShape = theShape->GetValue();
271 if (aShape.IsNull()) {
272 SetErrorCode("Shape is not defined");
276 gp_Trsf aTrsfInv = aTrsf.Inverted();
278 // int expectedGroups = 0;
279 // if (shapeType == TSHAPE_BASIC)
280 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
281 // expectedGroups = 10;
283 // expectedGroups = 11;
284 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
285 // expectedGroups = 12;
287 double aR1Ext = theR1 + theW1;
288 double aR2Ext = theR2 + theW2;
290 /////////////////////////
291 //// Groups of Faces ////
292 /////////////////////////
295 // Comment the following lines when GetInPlace bug is solved
297 // Workaround of GetInPlace bug
298 // Create a bounding box that fits the shape
299 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
300 aBox->GetLastFunction()->SetDescription("");
301 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
302 aBox->GetLastFunction()->SetDescription("");
303 // Apply transformation to box
304 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
305 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
306 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
308 // Get the shell of the box
309 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
310 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
311 aBox->GetLastFunction()->SetDescription("");
312 aShell->GetLastFunction()->SetDescription("");
313 // Get the common shapes between shell and shape
314 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean (theShape, aShell, 1); // MakeCommon
315 if (aCommonCompound.IsNull()) {
316 SetErrorCode(myBooleanOperations->GetErrorCode());
319 aCommonCompound->GetLastFunction()->SetDescription("");
320 // Explode the faces of common shapes => 3 faces
321 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
322 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
323 aCommonCompound->GetLastFunction()->SetDescription("");
324 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
326 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
327 std::list<Handle(GEOM_Object)> aFacesList;
328 for (int j = 1 ; j <= 4 ; j++) {
329 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
330 if (!aFace.IsNull()) {
331 aFace->GetLastFunction()->SetDescription("");
332 aFacesList.push_back(aFace);
335 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
336 if (!aCompoundOfFaces.IsNull()) {
337 aCompoundOfFaces->GetLastFunction()->SetDescription("");
338 aCompoundOfFacesList.push_back(aCompoundOfFaces);
342 if (aCompoundOfFacesList.size() == 3) {
343 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
344 aCompoundOfFacesList.pop_front();
345 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
346 aCompoundOfFacesList.pop_front();
347 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
348 aCompoundOfFacesList.pop_front();
353 // Uncomment the following lines when GetInPlace bug is solved
355 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
356 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
357 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
358 // aP1->GetLastFunction()->SetDescription("");
359 // aP2->GetLastFunction()->SetDescription("");
360 // aP3->GetLastFunction()->SetDescription("");
361 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
362 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
363 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
364 // aV1->GetLastFunction()->SetDescription("");
365 // aV2->GetLastFunction()->SetDescription("");
366 // aV3->GetLastFunction()->SetDescription("");
367 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
368 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
369 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
370 // aPln1->GetLastFunction()->SetDescription("");
371 // aPln2->GetLastFunction()->SetDescription("");
372 // aPln3->GetLastFunction()->SetDescription("");
374 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
375 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
376 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
377 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
378 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
379 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
380 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
381 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
382 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
386 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
387 if (junctionFaces1.IsNull())
388 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
389 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
390 if (!junctionFaces1.IsNull()) {
391 junctionFaces1->GetLastFunction()->SetDescription("");
392 junctionFaces1->SetName("JUNCTION_FACE_1");
393 theSeq->Append(junctionFaces1);
396 SetErrorCode("Junction face 1 not found");
397 // theSeq->Append(aPln1);
400 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
401 if (junctionFaces2.IsNull())
402 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
403 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
404 if (!junctionFaces2.IsNull()) {
405 junctionFaces2->GetLastFunction()->SetDescription("");
406 junctionFaces2->SetName("JUNCTION_FACE_2");
407 theSeq->Append(junctionFaces2);
410 SetErrorCode("Junction face 2 not found");
411 // theSeq->Append(aPln2);
414 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
415 if (junctionFaces3.IsNull())
416 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
417 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
418 if (!junctionFaces3.IsNull()) {
419 junctionFaces3->GetLastFunction()->SetDescription("");
420 junctionFaces3->SetName("JUNCTION_FACE_3");
421 theSeq->Append(junctionFaces3);
424 SetErrorCode("Junction face 3 not found");
425 // theSeq->Append(aPln3);
428 // Comment the following lines when GetInPlace bug is solved
433 /////////////////////////
434 //// Groups of Edges ////
435 /////////////////////////
436 // Result of propagate
438 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
440 TCollection_AsciiString theDesc = aFunction->GetDescription();
441 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
442 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
443 SetErrorCode("Propagation groups not found");
446 Standard_Integer aNbGroups = aSeqPropagate->Length();
447 // Recover previous description to get rid of Propagate dump
448 aFunction->SetDescription(theDesc);
450 #ifdef FIND_GROUPS_BY_POINTS
451 // BEGIN: new groups search
458 // g / ''..| | |..'' \
460 // .---.--'.. | | | ..'--.---.
461 // |a \ '''...........''' / |
462 // |-------\------' | '------/-------.
467 // ._________________|_________________.
473 // |-----------------|-----------------|
475 // '-----------------'-----------------'
478 // "Thickness" group (a)
479 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
480 aPntA.Transform(aTrsf);
481 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
482 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
483 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
485 // "Circular quarter of pipe" group (b)
486 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
487 aPntB.Transform(aTrsf);
488 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
489 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
490 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
492 // "Circular quarter of pipe" group (c)
493 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
494 aPntC.Transform(aTrsf);
495 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
496 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
497 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
499 // "Main pipe half length" group (d)
500 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
501 aPntD.Transform(aTrsf);
502 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
503 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
504 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
506 // "Incident pipe half length" group (e)
507 double aTol10 = Precision::Confusion() * 10.;
508 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
509 aPntE.Transform(aTrsf);
510 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
511 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
512 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
514 // "Flange" group (f)
515 double aFx = - aR2Ext - aTol10;
516 if (shapeType == TSHAPE_CHAMFER)
518 else if (shapeType == TSHAPE_FILLET)
520 gp_Pnt aPntF (aFx, 0, aR1Ext);
521 aPntF.Transform(aTrsf);
522 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
523 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
524 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
526 // "Chamfer or Fillet" group (g)
527 TopoDS_Shape anEdgeG;
528 if (shapeType == TSHAPE_CHAMFER) {
529 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
530 aPntG.Transform(aTrsf);
531 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
532 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
533 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
535 else if (shapeType == TSHAPE_FILLET) {
536 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
537 aPntG.Transform(aTrsf);
538 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
539 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
540 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
543 for (int i = 1 ; i <= aNbGroups; i++) {
544 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
548 TopoDS_Shape aGroupShape = aGroup->GetValue();
549 TopTools_IndexedMapOfShape anEdgesMap;
550 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
552 if (anEdgesMap.Contains(anEdgeA)) { // a
553 aGroup->SetName("THICKNESS");
554 theSeq->Append(aGroup);
556 else if (anEdgesMap.Contains(anEdgeB)) { // b
557 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
558 theSeq->Append(aGroup);
560 else if (anEdgesMap.Contains(anEdgeC)) { // c
561 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
562 theSeq->Append(aGroup);
564 else if (anEdgesMap.Contains(anEdgeD)) { // d
565 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
566 theSeq->Append(aGroup);
568 else if (anEdgesMap.Contains(anEdgeE)) { // e
569 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
570 theSeq->Append(aGroup);
572 else if (anEdgesMap.Contains(anEdgeF)) { // f
573 aGroup->SetName("FLANGE");
574 theSeq->Append(aGroup);
576 else if (shapeType == TSHAPE_CHAMFER) { // g
577 if (anEdgesMap.Contains(anEdgeG)) {
578 aGroup->SetName("CHAMFER");
579 theSeq->Append(aGroup);
582 else if (shapeType == TSHAPE_FILLET) { // g
583 if (anEdgesMap.Contains(anEdgeG)) {
584 aGroup->SetName("FILLET");
585 theSeq->Append(aGroup);
591 // END: new groups search
594 bool circularFoundAndAdded = false;
595 bool circularFound10 = false;
596 bool incidentPipeFound = false;
597 bool mainPipeFound = false;
598 bool mainPipeFoundAndAdded = false;
599 bool radialFound =false;
600 bool flangeFound = false;
601 bool flangeFoundAndAdded = false;
602 bool chamferOrFilletFound = false;
604 for (int i = 1 ; i <= aNbGroups; i++) {
607 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
611 TopoDS_Shape aGroupShape = aGroup->GetValue();
612 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
613 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
615 TopTools_IndexedMapOfShape anEdgesMap;
616 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
617 Standard_Integer nbEdges = anEdgesMap.Extent();
619 if (shapeType == TSHAPE_BASIC) {
620 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
622 aGroup->SetName("THICKNESS");
624 else if (nbEdges == 6) {
625 if (!circularFoundAndAdded) {
626 circularFoundAndAdded = true;
628 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
631 else if (nbEdges == 8) {
632 incidentPipeFound = true;
633 mainPipeFound = false;
637 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
639 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
640 double x=aP.X(), y=aP.Y(), z=aP.Z();
643 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
644 (Abs(y) > aR2Ext + Precision::Confusion())) {
645 incidentPipeFound = false;
648 if ( z < -Precision::Confusion()) {
649 // length of main pipe
650 mainPipeFound = true;
651 if (!mainPipeFoundAndAdded) {
652 mainPipeFoundAndAdded = true;
654 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
658 else if (Abs(x) > (theL1-Precision::Confusion())) {
659 // discretisation circulaire
661 if (!circularFoundAndAdded) {
662 circularFoundAndAdded = true;
664 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
669 if (incidentPipeFound) {
671 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
673 if (!addGroup && (!incidentPipeFound &&
677 // Flange (collerette)
680 aGroup->SetName("FLANGE");
686 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
687 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
689 aGroup->SetName("THICKNESS");
691 else if ((nbEdges == 10) || (nbEdges == 6)) {
692 if (!circularFoundAndAdded) {
694 circularFoundAndAdded = true;
695 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
697 circularFound10 = true;
700 else if (!circularFound10 && nbEdges == 10) {
701 circularFound10 = true;
703 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
706 else if (nbEdges == 8) {
707 incidentPipeFound = true;
708 mainPipeFound = true;
711 bool isNearZ0 = false;
712 bool isBelowZ0 = false;
714 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
716 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
717 double x=aP.X(), y=aP.Y(), z=aP.Z();
719 // tuy_princ_long_avant & tuy_princ_long_apres
720 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
721 // ((y <= aR1Ext + Precision::Confusion()) ||
722 // (y <= -(aR1Ext + Precision::Confusion())) ||
723 // (y <= theR1 + Precision::Confusion()) ||
724 // (y == -(theR1 + Precision::Confusion()))));
725 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
726 (fabs(y) > theR1 - Precision::Confusion() ||
727 fabs(y) < Precision::Confusion()));
730 mainPipeFound = false;
734 //if (z < Precision::Confusion() && !isMain) {
735 // flangeFound = true;
736 // if (!flangeFoundAndAdded) {
737 // flangeFoundAndAdded = true;
739 // aGroup->SetName("FLANGE");
742 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
743 if (z < - Precision::Confusion()) isBelowZ0 = true;
746 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
747 (Abs(y) > aR2Ext + Precision::Confusion())) {
748 incidentPipeFound = false;
754 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
756 if (incidentPipeFound) {
758 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
760 if (isNearZ0 && !isBelowZ0) {
762 if (!flangeFoundAndAdded) {
763 flangeFoundAndAdded = true;
765 aGroup->SetName("FLANGE");
768 if (!addGroup && (!incidentPipeFound &&
771 !chamferOrFilletFound)) {
773 chamferOrFilletFound = true;
774 if (shapeType == TSHAPE_CHAMFER)
775 aGroup->SetName("CHAMFER");
777 aGroup->SetName("FILLET");
783 // Add group to the list
785 theSeq->Append(aGroup);
793 bool GEOMImpl_IAdvancedOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
794 double theR1, double theW1, double theL1,
795 double theR2, double theW2, double theL2,
796 double theH, double theW,
797 double theRF, bool isNormal)
801 // Build tools for partition operation:
802 // 1 face and 2 planes
804 Handle(GEOM_Object) arete_intersect_int;
805 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
806 Handle(GEOM_Object) chan_racc;
807 Handle(GEOM_Object) vi1, vi2;
808 Handle(GEOM_Object) Te3;
811 #if OCC_VERSION_LARGE > 0x06010000
814 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
815 Vector_Z->GetLastFunction()->SetDescription("");
818 double aSize = 2*(theL1 + theL2);
819 double aR1Ext = theR1 + theW1;
820 double aR2Ext = theR2 + theW2;
821 double theVertCylinderRadius = aR2Ext + theW + theRF;
822 double theHoriCylinderRadius = aR1Ext + theH + theRF;
824 // Common edges on internal cylinder
825 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
826 box_i->GetLastFunction()->SetDescription("");
827 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
828 box_i->GetLastFunction()->SetDescription("");
830 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
831 TCollection_AsciiString theDesc = aFunction->GetDescription();
832 Handle(TColStd_HSequenceOfTransient) edges_i =
833 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
834 // Recover previous description to get rid of Propagate dump
835 aFunction->SetDescription(theDesc);
836 if (edges_i.IsNull() || edges_i->Length() == 0) {
837 SetErrorCode("Internal edges not found");
840 for (int i=1; i<=edges_i->Length();i++) {
841 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
842 anObj->GetLastFunction()->SetDescription("");
844 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
846 // search for vertices located on both internal pipes
847 aFunction = theShape->GetLastFunction();
848 theDesc = aFunction->GetDescription();
849 Handle(TColStd_HSequenceOfTransient) vertices_i =
850 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
851 // Recover previous description to get rid of Propagate dump
852 aFunction->SetDescription(theDesc);
853 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
854 SetErrorCode("Internal vertices not found");
858 for (int i = 1; i <= vertices_i->Length(); i++) {
859 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
860 v->GetLastFunction()->SetDescription("");
861 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
862 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
863 // std::cout << "Coords: " << aP.X() << ", " << aP.Y() << ", " << aP.Z() << std::endl;
864 if (Abs(aP.X()) <= Precision::Confusion()) {
865 if (Abs(aP.Y()) - theR1 <= Precision::Confusion()) {
868 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
869 if (Abs(aP.X()) - theR1 <= Precision::Confusion()) {
875 std::list<Handle(GEOM_Object)> theShapes;
878 Handle(GEOM_Object) ve1, ve2;
880 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
881 box_e->GetLastFunction()->SetDescription("");
882 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
883 box_e->GetLastFunction()->SetDescription("");
884 // Common edges on external cylinder
885 aFunction = theShape->GetLastFunction();
886 theDesc = aFunction->GetDescription();
887 Handle(TColStd_HSequenceOfTransient) edges_e =
888 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
889 // Recover previous description to get rid of Propagate dump
890 aFunction->SetDescription(theDesc);
891 if (edges_e.IsNull() || edges_e->Length() == 0) {
892 SetErrorCode("External edges not found");
895 for (int i=1; i<=edges_e->Length();i++) {
896 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
897 anObj->GetLastFunction()->SetDescription("");
900 // search for vertices located on both external pipes
901 aFunction = theShape->GetLastFunction();
902 theDesc = aFunction->GetDescription();
903 Handle(TColStd_HSequenceOfTransient) vertices_e =
904 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
905 // Recover previous description to get rid of Propagate dump
906 aFunction->SetDescription(theDesc);
907 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
908 SetErrorCode("External vertices not found");
912 for (int i = 1; i <= vertices_e->Length(); i++) {
913 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
914 v->GetLastFunction()->SetDescription("");
915 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
916 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
917 // std::cout << "Coords: " << aP.X() << ", " << aP.Y() << ", " << aP.Z() << std::endl;
918 if (Abs(aP.X()) <= Precision::Confusion()) {
919 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
922 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
923 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
927 if ( !ve1.IsNull() && !ve2.IsNull())
930 Handle(GEOM_Object) edge_e1, edge_e2;
932 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
933 if (edge_e1.IsNull()) {
934 SetErrorCode("Edge 1 could not be built");
938 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
939 if (edge_e2.IsNull()) {
940 SetErrorCode("Edge 2 could not be built");
944 edge_e1->GetLastFunction()->SetDescription("");
945 edge_e2->GetLastFunction()->SetDescription("");
947 std::list<Handle(GEOM_Object)> edge_e_elist;
948 edge_e_elist.push_back(arete_intersect_int);
949 edge_e_elist.push_back(edge_e1);
950 edge_e_elist.push_back(Handle(GEOM_Object)::DownCast(edges_e->Value(1)));
951 edge_e_elist.push_back(edge_e2);
952 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
953 if (wire_t.IsNull()) {
954 SetErrorCode("Impossible to build wire");
957 wire_t->GetLastFunction()->SetDescription("");
958 face_t = myShapesOperations->MakeFace(wire_t, false);
959 if (face_t.IsNull()) {
960 SetErrorCode("Impossible to build face");
963 face_t->GetLastFunction()->SetDescription("");
965 theShapes.push_back(theShape);
966 theShapes.push_back(vi1);
967 theShapes.push_back(vi2);
968 theShapes.push_back(ve1);
969 theShapes.push_back(ve2);
970 theShapes.push_back(edge_e1);
971 theShapes.push_back(edge_e2);
972 theShapes.push_back(wire_t);
973 theShapes.push_back(face_t);
976 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
977 int idP1, idP2, idP3, idP4;
982 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
983 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
984 box_e->GetLastFunction()->SetDescription("");
985 box_e = myTransformOperations->TranslateDXDYDZ
986 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
987 box_e->GetLastFunction()->SetDescription("");
989 aFunction = theShape->GetLastFunction();
990 theDesc = aFunction->GetDescription();
991 Handle(TColStd_HSequenceOfTransient) extremVertices =
992 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
993 // Recover previous description to get rid of Propagate dump
994 aFunction->SetDescription(theDesc);
996 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
998 SetErrorCode("Vertices on chamfer not found");
1000 SetErrorCode("Vertices on fillet not found");
1004 theShapes.push_back(theShape);
1005 theShapes.push_back(box_e);
1006 if (extremVertices->Length() != 6) {
1007 // for (int i=1; i<=extremVertices->Length(); i++){
1008 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1010 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1011 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1012 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1013 SetErrorCode("Bad number of vertices on chamfer found");
1017 for (int i=1; i<=extremVertices->Length(); i++){
1018 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1019 aV->GetLastFunction()->SetDescription("");
1020 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1022 if (Abs(aP.X()) <= Precision::Confusion()) {
1023 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1025 if (aP.Z()-ZX > Precision::Confusion()) {
1032 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1034 if (aP.Z() - ZY > Precision::Confusion()) {
1045 if (LX.at(0) == PZX)
1048 if (LY.at(0) == PZY)
1051 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1052 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1053 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1054 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1056 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1057 if (Cote_1.IsNull()) {
1058 SetErrorCode("Impossible to build edge in thickness");
1061 Cote_1->GetLastFunction()->SetDescription("");
1063 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1064 if (Cote_2.IsNull()) {
1065 SetErrorCode("Impossible to build edge in thickness");
1068 Cote_2->GetLastFunction()->SetDescription("");
1070 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1071 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1072 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1073 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1074 if (edge_chan_princ.IsNull()) {
1075 SetErrorCode("Impossible to find edge on main pipe");
1078 edge_chan_princ->GetLastFunction()->SetDescription("");
1080 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1081 if (edge_chan_inc.IsNull()) {
1082 SetErrorCode("Impossible to find edge on incident pipe");
1085 edge_chan_inc->GetLastFunction()->SetDescription("");
1087 std::list<Handle(GEOM_Object)> edgeList1;
1088 edgeList1.push_back(edge_chan_princ);
1089 edgeList1.push_back(Cote_1);
1090 edgeList1.push_back(arete_intersect_int);
1091 edgeList1.push_back(Cote_2);
1093 // std::cerr << "Creating wire 1" << std::endl;
1094 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1095 if (wire_t.IsNull()) {
1096 SetErrorCode("Impossible to build wire");
1099 wire_t->GetLastFunction()->SetDescription("");
1101 // std::cerr << "Creating face 1" << std::endl;
1102 face_t = myShapesOperations->MakeFace(wire_t, false);
1103 if (face_t.IsNull()) {
1104 SetErrorCode("Impossible to build face");
1107 face_t->GetLastFunction()->SetDescription("");
1108 theShapes.push_back(face_t);
1110 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1111 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1112 double deltaZ = aP2.Z() - aP5.Z();
1113 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1114 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1115 if (P5bis.IsNull()) {
1116 SetErrorCode("Impossible to translate vertex");
1119 P5bis->GetLastFunction()->SetDescription("");
1121 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1122 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1123 deltaZ = aP4.Z() - aP6.Z();
1124 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1125 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1126 if (P6bis.IsNull()) {
1127 SetErrorCode("Impossible to translate vertex");
1130 P6bis->GetLastFunction()->SetDescription("");
1132 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1133 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1134 if (Cote_3.IsNull()) {
1135 SetErrorCode("Impossible to build edge in thickness");
1138 Cote_3->GetLastFunction()->SetDescription("");
1140 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1141 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1142 if (Cote_4.IsNull()) {
1143 SetErrorCode("Impossible to build edge in thickness");
1146 Cote_4->GetLastFunction()->SetDescription("");
1148 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1149 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1150 if (Cote_4.IsNull()) {
1151 SetErrorCode("Impossible to build edge in thickness");
1154 Cote_5->GetLastFunction()->SetDescription("");
1156 //std::list<Handle(GEOM_Object)> edgeList2;
1157 //edgeList2.push_back(edge_chan_inc);
1158 //edgeList2.push_back(Cote_3);
1159 //edgeList2.push_back(Cote_5);
1160 //edgeList2.push_back(Cote_4);
1161 // std::cerr << "Creating wire 2" << std::endl;
1162 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1163 //if (wire_t2.IsNull()) {
1164 // SetErrorCode("Impossible to build wire");
1167 //wire_t2->GetLastFunction()->SetDescription("");
1168 // std::cerr << "Creating face 2" << std::endl;
1169 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1171 // Mantis issue 0021682
1172 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1173 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1174 if (face_t2.IsNull()) {
1175 SetErrorCode("Impossible to build face");
1178 face_t2->GetLastFunction()->SetDescription("");
1179 theShapes.push_back(face_t2);
1183 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1184 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1185 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1186 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1187 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1188 aP0->GetLastFunction()->SetDescription("");
1189 aVZ->GetLastFunction()->SetDescription("");
1190 aVXZ->GetLastFunction()->SetDescription("");
1191 aPlnOZ->GetLastFunction()->SetDescription("");
1192 aPlnOXZ->GetLastFunction()->SetDescription("");
1193 theShapes.push_back(aPlnOZ);
1194 theShapes.push_back(aPlnOXZ);
1197 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1198 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1199 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1200 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1201 Handle(TColStd_HArray1OfInteger) theMaterials;
1203 partitionShapes->Append(theShape);
1204 theTools->Append(aPlnOZ);
1205 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1206 theTools->Append(aPlnOXZ);
1207 theTools->Append(face_t);
1209 theTools->Append(face_t2);
1211 Te3 = myBooleanOperations->MakePartition
1212 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1213 TopAbs_SOLID, false, theMaterials, 0, false);
1215 SetErrorCode("Impossible to build partition of TShape");
1218 Te3->GetLastFunction()->SetDescription("");
1220 // Last verification: result should be a block
1221 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1222 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3,errList)) {
1223 SetErrorCode("TShape is not a compound of block");
1227 // // BEGIN Compound of created shapes - Only for debug purpose
1228 // theShapes.clear();
1229 // theShapes.push_back(theShape);
1230 // theShapes.push_back(aPlnOZ);
1231 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1232 // theShapes.push_back(aPlnOXZ);
1233 // theShapes.push_back(face_t);
1235 // theShapes.push_back(face_t2);
1237 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1238 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1239 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1240 // // END Compound of created shapes - Only for debug purpose
1242 TopoDS_Shape aShape = Te3->GetValue();
1243 theShape->GetLastFunction()->SetValue(aShape);
1245 catch (Standard_Failure) {
1246 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1247 SetErrorCode(aFail->GetMessageString());
1255 // Mirror and glue faces
1256 bool GEOMImpl_IAdvancedOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1257 double theR1, double theW1, double theL1,
1258 double theR2, double theW2, double theL2)
1263 double aSize = 2*(theL1 + theL2);
1264 double aR1Ext = theR1 + theW1;
1267 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1268 aP0->GetLastFunction()->SetDescription("");
1269 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1270 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1271 aVX->GetLastFunction()->SetDescription("");
1272 aVY->GetLastFunction()->SetDescription("");
1273 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1274 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1275 aPlane_OX->GetLastFunction()->SetDescription("");
1276 aPlane_OY->GetLastFunction()->SetDescription("");
1278 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1280 SetErrorCode("Impossible to build mirror of quarter TShape");
1284 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1286 SetErrorCode("Impossible to build mirror of half TShape");
1290 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1292 SetErrorCode("Impossible to build mirror of half TShape");
1296 std::list<Handle(GEOM_Object)> aShapesList;
1297 aShapesList.push_back(theShape);
1298 aShapesList.push_back(Te4);
1299 aShapesList.push_back(Te5);
1300 aShapesList.push_back(Te6);
1301 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1303 SetErrorCode("Impossible to build compound");
1307 // Copy source shape
1308 TopoDS_Shape aShapeCopy;
1309 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1310 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1312 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
1314 SetErrorCode("Impossible to glue faces of TShape");
1318 TopoDS_Shape aShape = Te8->GetValue();
1319 BRepCheck_Analyzer anAna (aShape, Standard_True);
1321 if (!anAna.IsValid()) {
1322 // Try to do gluing with the tolerance equal to maximal
1323 // tolerance of vertices of the source shape.
1324 Standard_Real aTolMax = -RealLast();
1326 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1327 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1328 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1330 if (aTol > aTolMax) {
1336 Te7->GetLastFunction()->SetValue(aShapeCopy);
1337 Te8 = myShapesOperations->MakeGlueFaces(Te7, aTolMax, true);
1340 SetErrorCode("Impossible to glue faces of TShape");
1344 aShape = Te8->GetValue();
1348 theShape->GetLastFunction()->SetValue(aShape);
1350 Te4->GetLastFunction()->SetDescription("");
1351 Te5->GetLastFunction()->SetDescription("");
1352 Te6->GetLastFunction()->SetDescription("");
1353 Te7->GetLastFunction()->SetDescription("");
1354 Te8->GetLastFunction()->SetDescription("");
1360 //=======================================================================
1361 //function : MakePipeTShapeThicknessReduction
1362 //purpose : Static method. Add thiskness reduction elements at the three
1363 // open ends of the T-Shape.
1364 //=======================================================================
1365 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakePipeTShapeThicknessReduction
1366 (TopoDS_Shape theShape,
1367 double r1, double w1, double l1,
1368 double r2, double w2, double l2,
1369 double rL, double wL, double ltransL, double lthinL,
1370 double rR, double wR, double ltransR, double lthinR,
1371 double rI, double wI, double ltransI, double lthinI,
1372 bool fuseReductions)
1374 // Add thickness reduction elements
1375 // at the three extremities: Left, Right and Incident
1377 // ---------------------.
1379 // ---------------------. \
1380 // ^ \ '-----------------.
1382 // | '-----------------'
1384 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1387 TopoDS_Shape aResult = theShape;
1388 double aTol = Precision::Confusion();
1390 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1392 // Left reduction (rL, wL, ltransL, lthinL)
1393 if (rL > aTol && wL > aTol && ltransL > aTol) {
1394 gp_Pnt aPLeft (-l1, 0, 0);
1395 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1396 TopoDS_Shape aReductionLeft = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1397 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1399 if (fuseReductions) {
1400 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1401 if (!fuseL.IsDone())
1402 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1403 aResult = fuseL.Shape();
1410 B.Add(C, aReductionLeft);
1416 if (rR > aTol && wR > aTol && ltransR > aTol) {
1417 gp_Pnt aPRight (l1, 0, 0);
1418 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1419 TopoDS_Shape aReductionRight = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1420 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1422 if (fuseReductions) {
1423 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1424 if (!fuseR.IsDone())
1425 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1426 aResult = fuseR.Shape();
1433 B.Add(C, aReductionRight);
1438 // Incident reduction
1439 if (rI > aTol && wI > aTol && ltransI > aTol) {
1440 gp_Pnt aPInci (0, 0, l2);
1441 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1442 TopoDS_Shape aReductionInci = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1443 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1445 if (fuseReductions) {
1446 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1447 if (!fuseInci.IsDone())
1448 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1449 aResult = fuseInci.Shape();
1456 B.Add(C, aReductionInci);
1461 // Get rid of extra compounds
1462 TopTools_ListOfShape listShapeRes;
1463 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1464 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1466 if (!fuseReductions && listShapeRes.Extent() > 1) {
1467 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1472 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1473 for (; itSub.More(); itSub.Next())
1474 B.Add(C, itSub.Value());
1477 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1483 //=======================================================================
1484 //function : MakeThicknessReduction
1485 //purpose : Static method. Create one thickness reduction element.
1486 //=======================================================================
1487 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1488 const double R, const double W,
1489 const double Rthin, const double Wthin,
1490 const double Ltrans, const double Lthin,
1493 double aTol = Precision::Confusion();
1494 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1495 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1497 bool isThinPart = (Lthin > aTol);
1502 // ^ \ '-----------------.
1504 // | '-----------------'
1506 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1509 double RExt = R + W;
1510 double RthinExt = Rthin + Wthin;
1512 gp_Dir aNormal = theAxes.Direction();
1513 gp_Dir anXDir = theAxes.XDirection();
1514 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1515 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1517 // Build the transition part
1518 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1519 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1522 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1523 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1524 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1526 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1527 TopoDS_Shape aReduction = cut1.Shape();
1529 // Build the thin part, if required
1530 TopoDS_Shape aThinPart;
1532 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1533 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1536 if (!CExt.IsDone() || !CInt.IsDone())
1537 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1538 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1540 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1541 aThinPart = cut2.Shape();
1547 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1548 if (!fuse1.IsDone())
1549 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1550 aReduction = fuse1.Shape();
1554 // Partition the reduction on blocks
1555 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1556 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1557 gp_Pln aPln1 (anAxesPln1);
1558 gp_Pln aPln2 (anAxesPln2);
1559 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1560 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1561 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1563 GEOMAlgo_Splitter PS;
1564 PS.AddShape(aReduction);
1566 PS.AddShape(aThinPart);
1569 PS.SetLimit(TopAbs_SOLID);
1572 aReduction = PS.Shape();
1578 //=============================================================================
1581 * \brief Create a T-shape object with specified caracteristics for the main and
1582 * the incident pipes (radius, width, half-length).
1583 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1584 * \param theR1 Internal radius of main pipe
1585 * \param theW1 Width of main pipe
1586 * \param theL1 Half-length of main pipe
1587 * \param theR2 Internal radius of incident pipe (R2 < R1)
1588 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1589 * \param theL2 Half-length of incident pipe
1590 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1591 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1593 //=============================================================================
1594 Handle(TColStd_HSequenceOfTransient)
1595 GEOMImpl_IAdvancedOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1596 double theR2, double theW2, double theL2,
1597 double theRL, double theWL, double theLtransL, double theLthinL,
1598 double theRR, double theWR, double theLtransR, double theLthinR,
1599 double theRI, double theWI, double theLtransI, double theLthinI,
1602 MESSAGE("GEOMImpl_IAdvancedOperations::MakePipeTShape");
1605 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1607 //Add a new shape function with parameters
1608 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1609 if (aFunction.IsNull()) return NULL;
1611 //Check if the function is set correctly
1612 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1614 GEOMImpl_IPipeTShape aData (aFunction);
1622 aData.SetHexMesh(theHexMesh);
1624 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1625 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1626 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1628 //Compute the resulting value
1630 #if OCC_VERSION_LARGE > 0x06010000
1633 if (!GetSolver()->ComputeFunction(aFunction)) {
1634 SetErrorCode("TShape driver failed");
1639 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1641 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1645 if (isTRL || isTRR || isTRI) {
1646 // Add thickness reduction elements
1647 // at the three extremities: Left, Right and Incident
1648 TopoDS_Shape aResShape =
1649 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
1650 theRL, theWL, theLtransL, theLthinL,
1651 theRR, theWR, theLtransR, theLthinR,
1652 theRI, theWI, theLtransI, theLthinI,
1654 aFunction->SetValue(aResShape);
1657 catch (Standard_Failure) {
1658 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1659 SetErrorCode(aFail->GetMessageString());
1663 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1664 aSeq->Append(aShape);
1669 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
1670 0., 0., 0., aSeq, gp_Trsf()))
1673 catch (Standard_Failure) {
1674 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1675 SetErrorCode(aFail->GetMessageString());
1680 //Make a Python command
1681 TCollection_AsciiString anEntry, aListRes("[");
1682 // Iterate over the sequence aSeq
1683 Standard_Integer aNbGroups = aSeq->Length();
1684 Standard_Integer i = 1;
1685 for (; i <= aNbGroups; i++) {
1686 Handle(Standard_Transient) anItem = aSeq->Value(i);
1687 if (anItem.IsNull()) continue;
1688 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1689 if (aGroup.IsNull()) continue;
1690 //Make a Python command
1691 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1692 aListRes += anEntry + ", ";
1694 aListRes.Trunc(aListRes.Length() - 2);
1696 GEOM::TPythonDump pd (aFunction);
1698 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
1699 << theR1 << ", " << theW1 << ", " << theL1 << ", "
1700 << theR2 << ", " << theW2 << ", " << theL2 << ", "
1703 // thickness reduction
1705 pd << ", theRL=" << theRL << ", theWL=" << theWL
1706 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
1708 pd << ", theRR=" << theRR << ", theWR=" << theWR
1709 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
1711 pd << ", theRI=" << theRI << ", theWI=" << theWI
1712 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
1721 //=============================================================================
1723 * MakePipeTShapeWithPosition
1724 * Create a T-shape object with specified caracteristics for the main and
1725 * the incident pipes (radius, width, half-length).
1726 * The extremities of the main pipe are located on junctions points P1 and P2.
1727 * The extremity of the incident pipe is located on junction point P3.
1728 * \param theR1 Internal radius of main pipe
1729 * \param theW1 Width of main pipe
1730 * \param theL1 Half-length of main pipe
1731 * \param theR2 Internal radius of incident pipe (R2 < R1)
1732 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1733 * \param theL2 Half-length of incident pipe
1734 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1735 * \param theP1 1st junction point of main pipe
1736 * \param theP2 2nd junction point of main pipe
1737 * \param theP3 Junction point of incident pipe
1738 * \return List of GEOM_Objects, containing the created shape and propagation groups..
1740 //=============================================================================
1741 Handle(TColStd_HSequenceOfTransient)
1742 GEOMImpl_IAdvancedOperations::MakePipeTShapeWithPosition
1743 (double theR1, double theW1, double theL1,
1744 double theR2, double theW2, double theL2,
1745 double theRL, double theWL, double theLtransL, double theLthinL,
1746 double theRR, double theWR, double theLtransR, double theLthinR,
1747 double theRI, double theWI, double theLtransI, double theLthinI,
1749 Handle(GEOM_Object) theP1,
1750 Handle(GEOM_Object) theP2,
1751 Handle(GEOM_Object) theP3)
1755 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1759 //Add a new shape function with parameters
1760 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1761 if (aFunction.IsNull()) return NULL;
1763 //Check if the function is set correctly
1764 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1766 // Check new position
1767 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
1771 GEOMImpl_IPipeTShape aData(aFunction);
1779 aData.SetHexMesh(theHexMesh);
1781 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1782 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1783 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1785 //Compute the resulting value
1787 #if OCC_VERSION_LARGE > 0x06010000
1790 if (!GetSolver()->ComputeFunction(aFunction)) {
1791 SetErrorCode("TShape driver failed");
1796 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1798 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1802 if (isTRL || isTRR || isTRI) {
1803 // Add thickness reduction elements
1804 // at the three extremities: Left, Right and Incident
1805 TopoDS_Shape aResShape =
1806 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
1807 theRL, theWL, theLtransL, theLthinL,
1808 theRR, theWR, theLtransR, theLthinR,
1809 theRI, theWI, theLtransI, theLthinI,
1811 aFunction->SetValue(aResShape);
1814 catch (Standard_Failure) {
1815 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1816 SetErrorCode(aFail->GetMessageString());
1820 TopoDS_Shape Te = aShape->GetValue();
1823 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
1824 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
1825 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
1826 aFunction->SetValue(aTrsf_Shape);
1828 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
1829 aSeq->Append(aShape);
1834 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
1835 0., 0., 0., aSeq, aTrsf)) {
1839 catch (Standard_Failure) {
1840 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1841 SetErrorCode(aFail->GetMessageString());
1846 //Make a Python command
1847 TCollection_AsciiString anEntry, aListRes("[");
1848 // Iterate over the sequence aSeq
1849 Standard_Integer aNbGroups = aSeq->Length();
1850 Standard_Integer i = 1;
1851 for (; i <= aNbGroups; i++) {
1852 Handle(Standard_Transient) anItem = aSeq->Value(i);
1853 if (anItem.IsNull()) continue;
1854 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
1855 if (aGroup.IsNull()) continue;
1856 //Make a Python command
1857 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
1858 aListRes += anEntry + ", ";
1860 aListRes.Trunc(aListRes.Length() - 2);
1862 GEOM::TPythonDump pd (aFunction);
1864 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
1865 << theR1 << ", " << theW1 << ", " << theL1 << ", "
1866 << theR2 << ", " << theW2 << ", " << theL2 << ", "
1867 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
1869 // thickness reduction
1871 pd << ", theRL=" << theRL << ", theWL=" << theWL
1872 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
1874 pd << ", theRR=" << theRR << ", theWR=" << theWR
1875 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
1877 pd << ", theRI=" << theRI << ", theWI=" << theWI
1878 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
1887 //=============================================================================
1889 * MakePipeTShapeChamfer
1890 * Create a T-shape object with specified caracteristics for the main and
1891 * the incident pipes (radius, width, half-length). A chamfer is created
1892 * on the junction of the pipes.
1893 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1894 * \param theR1 Internal radius of main pipe
1895 * \param theW1 Width of main pipe
1896 * \param theL1 Half-length of main pipe
1897 * \param theR2 Internal radius of incident pipe (R2 < R1)
1898 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1899 * \param theL2 Half-length of incident pipe
1900 * \param theH Height of chamfer.
1901 * \param theW Width of chamfer.
1902 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1903 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1905 //=============================================================================
1906 Handle(TColStd_HSequenceOfTransient)
1907 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamfer
1908 (double theR1, double theW1, double theL1,
1909 double theR2, double theW2, double theL2,
1910 double theRL, double theWL, double theLtransL, double theLthinL,
1911 double theRR, double theWR, double theLtransR, double theLthinR,
1912 double theRI, double theWI, double theLtransI, double theLthinI,
1913 double theH, double theW,
1918 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1919 //Add a new shape function with parameters
1920 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
1921 if (aFunction.IsNull()) return NULL;
1923 //Check if the function is set correctly
1924 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1926 GEOMImpl_IPipeTShape aData(aFunction);
1936 aData.SetHexMesh(theHexMesh);
1938 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1939 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1940 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1942 //Compute the resulting value
1944 #if OCC_VERSION_LARGE > 0x06010000
1947 if (!GetSolver()->ComputeFunction(aFunction)) {
1948 SetErrorCode("TShape driver failed");
1952 catch (Standard_Failure) {
1953 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1954 SetErrorCode(aFail->GetMessageString());
1959 TopoDS_Shape aShapeShape = aShape->GetValue();
1960 TopTools_IndexedMapOfShape anEdgesIndices;
1961 TopExp::MapShapes(aShapeShape, anEdgesIndices);
1962 // Common edges on external cylinders
1963 Handle(GEOM_Object) box_e;
1965 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
1968 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
1970 box_e->GetLastFunction()->SetDescription("");
1971 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
1972 box_e->GetLastFunction()->SetDescription("");
1974 Handle(TColStd_HSequenceOfInteger) edges_e =
1975 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1976 box_e->GetLastFunction()->SetDescription("");
1978 if (edges_e.IsNull() || edges_e->Length() == 0) {
1979 SetErrorCode("External edges not found");
1982 int nbEdgesInChamfer = 0;
1983 std::list<int> theEdges;
1984 for (int i=1; i<=edges_e->Length();i++) {
1985 int edgeID = edges_e->Value(i);
1986 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
1987 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
1991 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
1992 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
1993 nbEdgesInChamfer ++;
1994 theEdges.push_back(edgeID);
1998 if (theHexMesh && nbEdgesInChamfer == 1)
2001 Handle(GEOM_Object) aChamfer;
2003 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2005 catch (Standard_Failure) {
2006 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2007 SetErrorCode(aFail->GetMessageString());
2010 if (aChamfer.IsNull()) {
2011 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2014 aChamfer->GetLastFunction()->SetDescription("");
2016 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2017 aFunction->SetValue(aChamferShape);
2021 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2023 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2027 // Add thickness reduction elements
2028 // at the three extremities: Left, Right and Incident
2030 #if OCC_VERSION_LARGE > 0x06010000
2033 if (isTRL || isTRR || isTRI) {
2034 TopoDS_Shape aResShape =
2035 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2036 theRL, theWL, theLtransL, theLthinL,
2037 theRR, theWR, theLtransR, theLthinR,
2038 theRI, theWI, theLtransI, theLthinI,
2040 aFunction->SetValue(aResShape);
2043 catch (Standard_Failure) {
2044 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2045 SetErrorCode(aFail->GetMessageString());
2049 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2050 aSeq->Append(aShape);
2055 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2056 theH, theW, 0., aSeq, gp_Trsf()))
2059 catch (Standard_Failure) {
2060 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2061 SetErrorCode(aFail->GetMessageString());
2066 //Make a Python command
2067 TCollection_AsciiString anEntry, aListRes("[");
2068 // Iterate over the sequence aSeq
2069 Standard_Integer aNbGroups = aSeq->Length();
2070 Standard_Integer i = 1;
2071 for (; i <= aNbGroups; i++) {
2072 Handle(Standard_Transient) anItem = aSeq->Value(i);
2073 if (anItem.IsNull()) continue;
2074 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2075 if (aGroup.IsNull()) continue;
2076 //Make a Python command
2077 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2078 aListRes += anEntry + ", ";
2080 aListRes.Trunc(aListRes.Length() - 2);
2082 GEOM::TPythonDump pd (aFunction);
2084 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2085 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2086 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2087 << theH << ", " << theW << ", " << theHexMesh;
2089 // thickness reduction
2091 pd << ", theRL=" << theRL << ", theWL=" << theWL
2092 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2094 pd << ", theRR=" << theRR << ", theWR=" << theWR
2095 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2097 pd << ", theRI=" << theRI << ", theWI=" << theWI
2098 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2107 //=============================================================================
2109 * MakePipeTShapeChamferWithPosition
2110 * Create a T-shape object with specified caracteristics for the main and
2111 * the incident pipes (radius, width, half-length). A chamfer is created
2112 * on the junction of the pipes.
2113 * The extremities of the main pipe are located on junctions points P1 and P2.
2114 * The extremity of the incident pipe is located on junction point P3.
2115 * \param theR1 Internal radius of main pipe
2116 * \param theW1 Width of main pipe
2117 * \param theL1 Half-length of main pipe
2118 * \param theR2 Internal radius of incident pipe (R2 < R1)
2119 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2120 * \param theL2 Half-length of incident pipe
2121 * \param theH Height of chamfer.
2122 * \param theW Width of chamfer.
2123 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2124 * \param theP1 1st junction point of main pipe
2125 * \param theP2 2nd junction point of main pipe
2126 * \param theP3 Junction point of incident pipe
2127 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2129 //=============================================================================
2130 Handle(TColStd_HSequenceOfTransient)
2131 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamferWithPosition
2132 (double theR1, double theW1, double theL1,
2133 double theR2, double theW2, double theL2,
2134 double theRL, double theWL, double theLtransL, double theLthinL,
2135 double theRR, double theWR, double theLtransR, double theLthinR,
2136 double theRI, double theWI, double theLtransI, double theLthinI,
2137 double theH, double theW,
2139 Handle(GEOM_Object) theP1,
2140 Handle(GEOM_Object) theP2,
2141 Handle(GEOM_Object) theP3)
2145 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2146 //Add a new shape function with parameters
2147 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2148 if (aFunction.IsNull()) return NULL;
2150 //Check if the function is set correctly
2151 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2153 // Check new position
2154 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2158 GEOMImpl_IPipeTShape aData(aFunction);
2168 aData.SetHexMesh(theHexMesh);
2170 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2171 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2172 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2174 //Compute the resulting value
2176 #if OCC_VERSION_LARGE > 0x06010000
2179 if (!GetSolver()->ComputeFunction(aFunction)) {
2180 SetErrorCode("TShape driver failed");
2184 catch (Standard_Failure) {
2185 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2186 SetErrorCode(aFail->GetMessageString());
2191 TopoDS_Shape aShapeShape = aShape->GetValue();
2192 TopTools_IndexedMapOfShape anEdgesIndices;
2193 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2194 // Common edges on external cylinders
2195 Handle(GEOM_Object) box_e;
2197 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2200 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2202 box_e->GetLastFunction()->SetDescription("");
2203 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2204 box_e->GetLastFunction()->SetDescription("");
2206 Handle(TColStd_HSequenceOfInteger) edges_e =
2207 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2208 box_e->GetLastFunction()->SetDescription("");
2210 if (edges_e.IsNull() || edges_e->Length() == 0) {
2211 SetErrorCode("External edges not found");
2214 int nbEdgesInChamfer = 0;
2215 std::list<int> theEdges;
2216 for (int i=1; i<=edges_e->Length();i++) {
2217 int edgeID = edges_e->Value(i);
2218 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2219 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2221 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2222 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2223 nbEdgesInChamfer ++;
2224 theEdges.push_back(edgeID);
2228 if (theHexMesh && nbEdgesInChamfer == 1)
2231 Handle(GEOM_Object) aChamfer;
2233 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2235 catch (Standard_Failure) {
2236 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2237 SetErrorCode(aFail->GetMessageString());
2240 if (aChamfer.IsNull()) {
2241 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2244 aChamfer->GetLastFunction()->SetDescription("");
2246 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2247 aFunction->SetValue(aChamferShape);
2251 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2253 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2257 // Add thickness reduction elements
2258 // at the three extremities: Left, Right and Incident
2260 #if OCC_VERSION_LARGE > 0x06010000
2263 if (isTRL || isTRR || isTRI) {
2264 TopoDS_Shape aResShape =
2265 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2266 theRL, theWL, theLtransL, theLthinL,
2267 theRR, theWR, theLtransR, theLthinR,
2268 theRI, theWI, theLtransI, theLthinI,
2270 aFunction->SetValue(aResShape);
2273 catch (Standard_Failure) {
2274 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2275 SetErrorCode(aFail->GetMessageString());
2280 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2281 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2282 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2283 aFunction->SetValue(aTrsf_Shape);
2285 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2286 aSeq->Append(aShape);
2291 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2292 theH, theW, 0., aSeq, aTrsf))
2295 catch (Standard_Failure) {
2296 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2297 SetErrorCode(aFail->GetMessageString());
2302 //Make a Python command
2303 TCollection_AsciiString anEntry, aListRes("[");
2304 // Iterate over the sequence aSeq
2305 Standard_Integer aNbGroups = aSeq->Length();
2306 Standard_Integer i = 1;
2307 for (; i <= aNbGroups; i++) {
2308 Handle(Standard_Transient) anItem = aSeq->Value(i);
2309 if (anItem.IsNull()) continue;
2310 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2311 if (aGroup.IsNull()) continue;
2312 //Make a Python command
2313 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2314 aListRes += anEntry + ", ";
2316 aListRes.Trunc(aListRes.Length() - 2);
2318 GEOM::TPythonDump pd (aFunction);
2320 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2321 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2322 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2323 << theH << ", " << theW << ", " << theHexMesh << ", "
2324 << theP1 << ", " << theP2 << ", " << theP3;
2326 // thickness reduction
2328 pd << ", theRL=" << theRL << ", theWL=" << theWL
2329 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2331 pd << ", theRR=" << theRR << ", theWR=" << theWR
2332 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2334 pd << ", theRI=" << theRI << ", theWI=" << theWI
2335 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2344 //=============================================================================
2346 * MakePipeTShapeFillet
2347 * Create a T-shape object with specified caracteristics for the main and
2348 * the incident pipes (radius, width, half-length). A fillet is created
2349 * on the junction of the pipes.
2350 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2351 * \param theR1 Internal radius of main pipe
2352 * \param theW1 Width of main pipe
2353 * \param theL1 Half-length of main pipe
2354 * \param theR2 Internal radius of incident pipe (R2 < R1)
2355 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2356 * \param theL2 Half-length of incident pipe
2357 * \param theRF Radius of curvature of fillet.
2358 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2359 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2361 //=============================================================================
2362 Handle(TColStd_HSequenceOfTransient)
2363 GEOMImpl_IAdvancedOperations::MakePipeTShapeFillet
2364 (double theR1, double theW1, double theL1,
2365 double theR2, double theW2, double theL2,
2366 double theRL, double theWL, double theLtransL, double theLthinL,
2367 double theRR, double theWR, double theLtransR, double theLthinR,
2368 double theRI, double theWI, double theLtransI, double theLthinI,
2369 double theRF, bool theHexMesh)
2373 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2374 //Add a new shape function with parameters
2375 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2376 if (aFunction.IsNull()) return NULL;
2378 //Check if the function is set correctly
2379 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2381 GEOMImpl_IPipeTShape aData(aFunction);
2390 aData.SetHexMesh(theHexMesh);
2392 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2393 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2394 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2396 //Compute the resulting value
2398 #if OCC_VERSION_LARGE > 0x06010000
2401 if (!GetSolver()->ComputeFunction(aFunction)) {
2402 SetErrorCode("TShape driver failed");
2406 catch (Standard_Failure) {
2407 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2408 SetErrorCode(aFail->GetMessageString());
2413 TopoDS_Shape aShapeShape = aShape->GetValue();
2414 TopTools_IndexedMapOfShape anEdgesIndices;
2415 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2416 // Common edges on external cylinders
2417 Handle(GEOM_Object) box_e;
2419 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2422 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2424 box_e->GetLastFunction()->SetDescription("");
2425 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2426 box_e->GetLastFunction()->SetDescription("");
2428 Handle(TColStd_HSequenceOfInteger) edges_e =
2429 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2430 box_e->GetLastFunction()->SetDescription("");
2432 if (edges_e.IsNull() || edges_e->Length() == 0) {
2433 SetErrorCode("External edges not found");
2436 int nbEdgesInFillet = 0;
2437 std::list<int> theEdges;
2438 for (int i=1; i<=edges_e->Length();i++) {
2439 int edgeID = edges_e->Value(i);
2440 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2441 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2443 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2444 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2446 theEdges.push_back(edgeID);
2450 if (theHexMesh && nbEdgesInFillet == 1)
2454 Handle(GEOM_Object) aFillet;
2456 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2458 catch (Standard_Failure) {
2459 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2460 SetErrorCode(aFail->GetMessageString());
2463 if (aFillet.IsNull()) {
2464 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2465 SetErrorCode(myLocalOperations->GetErrorCode());
2468 aFillet->GetLastFunction()->SetDescription("");
2470 TopoDS_Shape aFilletShape = aFillet->GetValue();
2471 aFunction->SetValue(aFilletShape);
2474 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2475 // the following block, when enabled, leads to partitioning problems
2477 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2478 // BEGIN: Limit tolerances (debug)
2479 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2480 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2481 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2482 aCorr1->GetLastFunction()->SetDescription("");
2483 // END: Limit tolerances (debug)
2484 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2486 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2489 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2491 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2495 // Add thickness reduction elements
2496 // at the three extremities: Left, Right and Incident
2498 #if OCC_VERSION_LARGE > 0x06010000
2501 if (isTRL || isTRR || isTRI) {
2502 TopoDS_Shape aResShape =
2503 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2504 theRL, theWL, theLtransL, theLthinL,
2505 theRR, theWR, theLtransR, theLthinR,
2506 theRI, theWI, theLtransI, theLthinI,
2508 aFunction->SetValue(aResShape);
2511 catch (Standard_Failure) {
2512 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2513 SetErrorCode(aFail->GetMessageString());
2517 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2518 aSeq->Append(aShape);
2523 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2524 0., 0., theRF, aSeq, gp_Trsf()))
2527 catch (Standard_Failure) {
2528 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2529 SetErrorCode(aFail->GetMessageString());
2534 //Make a Python command
2535 TCollection_AsciiString anEntry, aListRes("[");
2536 // Iterate over the sequence aSeq
2537 Standard_Integer aNbGroups = aSeq->Length();
2538 Standard_Integer i = 1;
2539 for (; i <= aNbGroups; i++) {
2540 Handle(Standard_Transient) anItem = aSeq->Value(i);
2541 if (anItem.IsNull()) continue;
2542 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2543 if (aGroup.IsNull()) continue;
2544 //Make a Python command
2545 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2546 aListRes += anEntry + ", ";
2548 aListRes.Trunc(aListRes.Length() - 2);
2550 GEOM::TPythonDump pd (aFunction);
2552 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2553 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2554 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2555 << theRF << ", " << theHexMesh;
2557 // thickness reduction
2559 pd << ", theRL=" << theRL << ", theWL=" << theWL
2560 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2562 pd << ", theRR=" << theRR << ", theWR=" << theWR
2563 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2565 pd << ", theRI=" << theRI << ", theWI=" << theWI
2566 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2575 //=============================================================================
2577 * MakePipeTShapeFilletWithPosition
2578 * \brief Create a T-shape object with specified caracteristics for the main and
2579 * the incident pipes (radius, width, half-length). A fillet is created
2580 * on the junction of the pipes.
2581 * The extremities of the main pipe are located on junctions points P1 and P2.
2582 * The extremity of the incident pipe is located on junction point P3.
2583 * \param theR1 Internal radius of main pipe
2584 * \param theW1 Width of main pipe
2585 * \param theL1 Half-length of main pipe
2586 * \param theR2 Internal radius of incident pipe (R2 < R1)
2587 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2588 * \param theL2 Half-length of incident pipe
2589 * \param theRF Radius of curvature of fillet
2590 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2591 * \param theP1 1st junction point of main pipe
2592 * \param theP2 2nd junction point of main pipe
2593 * \param theP3 Junction point of incident pipe
2594 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2596 //=============================================================================
2597 Handle(TColStd_HSequenceOfTransient)
2598 GEOMImpl_IAdvancedOperations::MakePipeTShapeFilletWithPosition
2599 (double theR1, double theW1, double theL1,
2600 double theR2, double theW2, double theL2,
2601 double theRL, double theWL, double theLtransL, double theLthinL,
2602 double theRR, double theWR, double theLtransR, double theLthinR,
2603 double theRI, double theWI, double theLtransI, double theLthinI,
2604 double theRF, bool theHexMesh,
2605 Handle(GEOM_Object) theP1,
2606 Handle(GEOM_Object) theP2,
2607 Handle(GEOM_Object) theP3)
2611 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2612 //Add a new shape function with parameters
2613 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2614 if (aFunction.IsNull()) return NULL;
2616 //Check if the function is set correctly
2617 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2619 // Check new position
2620 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2624 GEOMImpl_IPipeTShape aData(aFunction);
2633 aData.SetHexMesh(theHexMesh);
2635 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2636 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2637 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2639 //Compute the resulting value
2641 #if OCC_VERSION_LARGE > 0x06010000
2644 if (!GetSolver()->ComputeFunction(aFunction)) {
2645 SetErrorCode("TShape driver failed");
2649 catch (Standard_Failure) {
2650 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2651 SetErrorCode(aFail->GetMessageString());
2656 TopoDS_Shape aShapeShape = aShape->GetValue();
2657 TopTools_IndexedMapOfShape anEdgesIndices;
2658 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2659 // Common edges on external cylinders
2660 Handle(GEOM_Object) box_e;
2662 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2665 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2667 box_e->GetLastFunction()->SetDescription("");
2668 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2669 box_e->GetLastFunction()->SetDescription("");
2671 Handle(TColStd_HSequenceOfInteger) edges_e =
2672 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2673 box_e->GetLastFunction()->SetDescription("");
2675 if (edges_e.IsNull() || edges_e->Length() == 0) {
2676 SetErrorCode("External edges not found");
2679 int nbEdgesInFillet = 0;
2680 std::list<int> theEdges;
2681 for (int i=1; i<=edges_e->Length();i++) {
2682 int edgeID = edges_e->Value(i);
2683 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2684 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2686 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2687 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2689 theEdges.push_back(edgeID);
2693 if (theHexMesh && nbEdgesInFillet == 1)
2697 Handle(GEOM_Object) aFillet;
2699 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2701 catch (Standard_Failure) {
2702 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2703 SetErrorCode(aFail->GetMessageString());
2706 if (aFillet.IsNull()) {
2707 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2710 aFillet->GetLastFunction()->SetDescription("");
2712 TopoDS_Shape aFilletShape = aFillet->GetValue();
2713 aFunction->SetValue(aFilletShape);
2716 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
2717 // the following block, when enabled, leads to partitioning problems
2719 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
2720 // BEGIN: Limit tolerances (debug)
2721 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2722 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2723 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2724 aCorr1->GetLastFunction()->SetDescription("");
2725 // END: Limit tolerances (debug)
2726 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
2728 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
2731 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2733 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2737 // Add thickness reduction elements
2738 // at the three extremities: Left, Right and Incident
2740 #if OCC_VERSION_LARGE > 0x06010000
2743 if (isTRL || isTRR || isTRI) {
2744 TopoDS_Shape aResShape =
2745 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2746 theRL, theWL, theLtransL, theLthinL,
2747 theRR, theWR, theLtransR, theLthinR,
2748 theRI, theWI, theLtransI, theLthinI,
2750 aFunction->SetValue(aResShape);
2753 catch (Standard_Failure) {
2754 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2755 SetErrorCode(aFail->GetMessageString());
2760 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2761 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2762 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2763 aFunction->SetValue(aTrsf_Shape);
2765 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2766 aSeq->Append(aShape);
2771 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2772 0., 0., theRF, aSeq, aTrsf))
2775 catch (Standard_Failure) {
2776 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2777 SetErrorCode(aFail->GetMessageString());
2782 //Make a Python command
2783 TCollection_AsciiString anEntry, aListRes("[");
2784 // Iterate over the sequence aSeq
2785 Standard_Integer aNbGroups = aSeq->Length();
2786 Standard_Integer i = 1;
2787 for (; i <= aNbGroups; i++) {
2788 Handle(Standard_Transient) anItem = aSeq->Value(i);
2789 if (anItem.IsNull()) continue;
2790 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2791 if (aGroup.IsNull()) continue;
2792 //Make a Python command
2793 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2794 aListRes += anEntry + ", ";
2796 aListRes.Trunc(aListRes.Length() - 2);
2798 GEOM::TPythonDump pd (aFunction);
2800 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2801 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2802 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2803 << theRF << ", " << theHexMesh << ", "
2804 << theP1 << ", " << theP2 << ", " << theP3;
2806 // thickness reduction
2808 pd << ", theRL=" << theRL << ", theWL=" << theWL
2809 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2811 pd << ", theRR=" << theRR << ", theWR=" << theWR
2812 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2814 pd << ", theRI=" << theRI << ", theWI=" << theWI
2815 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2824 //=============================================================================
2826 * This function allows to create a disk already divided into blocks. It can be
2827 * used to create divided pipes for later meshing in hexaedra.
2828 * \param theR Radius of the disk
2829 * \param theRatio Relative size of the central square diagonal against the disk diameter
2830 * \param theOrientation Plane on which the disk will be built
2831 * \param thePattern The division pattern of the disk (hexagon or square in the center)
2832 * \return New GEOM_Object, containing the created shape.
2834 //=============================================================================
2835 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedDisk (double theR, double theRatio,
2836 int theOrientation, int thePattern)
2840 if (theOrientation != 1 &&
2841 theOrientation != 2 &&
2842 theOrientation != 3)
2844 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
2848 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
2850 //Add a new shape function with parameters
2851 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
2852 if (aFunction.IsNull()) return NULL;
2854 //Check if the function is set correctly
2855 if (aFunction->GetDriverGUID() != GEOMImpl_DividedDiskDriver::GetID()) return NULL;
2857 GEOMImpl_IDividedDisk aData (aFunction);
2860 aData.SetRatio(theRatio);
2861 aData.SetOrientation(theOrientation);
2862 aData.SetType(thePattern);
2864 //Compute the resulting value
2866 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
2869 if (!GetSolver()->ComputeFunction(aFunction)) {
2870 SetErrorCode("DividedDisk driver failed");
2874 catch (Standard_Failure) {
2875 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2876 SetErrorCode(aFail->GetMessageString());
2880 std::string aPatternStr;
2885 aPatternStr = "GEOM.SQUARE";
2888 aPatternStr = "GEOM.HEXAGON";
2892 //Make a Python command
2893 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
2900 //=============================================================================
2902 * This function allows to create a disk already divided into blocks. It can be
2903 * used to create divided pipes for later meshing in hexaedra.
2904 * \param theR Radius of the disk
2905 * \param theRatio Relative size of the central square diagonal against the disk diameter
2906 * \return New GEOM_Object, containing the created shape.
2908 //=============================================================================
2909 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
2910 Handle(GEOM_Object) theVec,
2918 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
2920 //Add a new shape function with parameters
2921 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
2922 if (aFunction.IsNull()) return NULL;
2924 //Check if the function is set correctly
2925 if (aFunction->GetDriverGUID() != GEOMImpl_DividedDiskDriver::GetID()) return NULL;
2927 GEOMImpl_IDividedDisk aData (aFunction);
2929 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
2930 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
2932 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
2934 aData.SetCenter(aRefPnt);
2935 aData.SetVector(aRefVec);
2938 aData.SetRatio(theRatio);
2939 aData.SetType(thePattern);
2941 //Compute the resulting value
2943 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
2946 if (!GetSolver()->ComputeFunction(aFunction)) {
2947 SetErrorCode("DividedDisk driver failed");
2951 catch (Standard_Failure) {
2952 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2953 SetErrorCode(aFail->GetMessageString());
2957 std::string aPatternStr;
2962 aPatternStr = "GEOM.SQUARE";
2965 aPatternStr = "GEOM.HEXAGON";
2970 //Make a Python command
2971 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
2978 //=============================================================================
2980 * Builds a cylinder prepared for hexa meshes
2981 * \param theR Radius of the cylinder
2982 * \param theH Height of the cylinder
2983 * \return New GEOM_Object, containing the created shape.
2985 //=============================================================================
2986 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedCylinder (double theR,
2993 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
2995 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
2996 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
2998 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3000 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3001 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3002 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3004 std::string aPatternStr;
3009 aPatternStr = "GEOM.SQUARE";
3012 aPatternStr = "GEOM.HEXAGON";
3016 //Make a Python command
3017 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3023 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/