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"
34 #include "GEOMAlgo_FinderShapeOn1.hxx"
36 #include "GEOMImpl_Gen.hxx"
37 #include "GEOMImpl_Types.hxx"
39 #include "GEOMImpl_IBasicOperations.hxx"
40 #include "GEOMImpl_IBooleanOperations.hxx"
41 #include "GEOMImpl_IShapesOperations.hxx"
42 #include "GEOMImpl_ITransformOperations.hxx"
43 #include "GEOMImpl_IBlocksOperations.hxx"
44 #include "GEOMImpl_I3DPrimOperations.hxx"
45 #include "GEOMImpl_ILocalOperations.hxx"
46 #include "GEOMImpl_IHealingOperations.hxx"
47 #include "GEOMImpl_IGroupOperations.hxx"
49 #include "GEOMImpl_GlueDriver.hxx"
50 #include "GEOMImpl_PipeTShapeDriver.hxx"
51 #include "GEOMImpl_IPipeTShape.hxx"
52 #include "GEOMImpl_DividedDiskDriver.hxx"
53 #include "GEOMImpl_IDividedDisk.hxx"
54 // #include "GEOMImpl_DividedCylinderDriver.hxx"
55 // #include "GEOMImpl_IDividedCylinder.hxx"
56 #include <GEOMImpl_SmoothingSurfaceDriver.hxx>
57 #include <GEOMImpl_ISmoothingSurface.hxx>
58 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/
60 #include <TDF_Tool.hxx>
61 #include <TFunction_DriverTable.hxx>
62 #include <TFunction_Driver.hxx>
63 #include <TFunction_Logbook.hxx>
64 #include <TNaming_CopyShape.hxx>
67 #include <TopExp_Explorer.hxx>
69 #include <TopoDS_Vertex.hxx>
70 #include <TopTools_IndexedMapOfShape.hxx>
71 #include <TopTools_ListIteratorOfListOfShape.hxx>
72 #include <TColStd_IndexedDataMapOfTransientTransient.hxx>
74 #include <BRep_Builder.hxx>
75 #include <BRep_Tool.hxx>
77 #include <BRepAdaptor_Surface.hxx>
78 #include <BRepAlgoAPI_Cut.hxx>
79 #include <BRepAlgoAPI_Fuse.hxx>
80 #include <BRepBuilderAPI_MakeFace.hxx>
81 #include <BRepBuilderAPI_MakeVertex.hxx>
82 #include <BRepBuilderAPI_Transform.hxx>
83 #include <BRepPrimAPI_MakeCone.hxx>
84 #include <BRepPrimAPI_MakeCylinder.hxx>
90 #include <GC_MakeConicalSurface.hxx>
91 #include <Geom_CylindricalSurface.hxx>
95 #include "AdvancedEngine_Types.hxx"
97 #include <Standard_Stream.hxx>
98 #include <Standard_Failure.hxx>
99 #include <StdFail_NotDone.hxx>
100 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
102 #define HALF_LENGTH_MAIN_PIPE "Main pipe half length" //"Tuyau principal - demi longueur"
103 #define HALF_LENGTH_INCIDENT_PIPE "Incident pipe half length" //"Tuyau incident - demi longueur"
104 #define CIRCULAR_QUARTER_PIPE "Circular quarter of pipe" //"Circulaire - quart de tuyau"
105 #define THICKNESS "Thickness" //"Epaisseur"
106 #define FLANGE "Flange" // "Collerette"
107 #define CHAMFER_OR_FILLET "Chamfer or fillet" //"Chanfrein ou Raccord"
108 #define JUNCTION_FACE_1 "Junction 1" //"Face de jonction 1"
109 #define JUNCTION_FACE_2 "Junction 2" //"Face de jonction 2"
110 #define JUNCTION_FACE_3 "Junction 3" //"Face de jonction 3"
112 #define FIND_GROUPS_BY_POINTS 1
114 //=============================================================================
118 //=============================================================================
119 GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations(GEOM_Engine* theEngine, int theDocID) :
120 GEOM_IOperations(theEngine, theDocID)
122 MESSAGE("GEOMImpl_IAdvancedOperations::GEOMImpl_IAdvancedOperations");
123 myBasicOperations = new GEOMImpl_IBasicOperations(GetEngine(), GetDocID());
124 myBooleanOperations = new GEOMImpl_IBooleanOperations(GetEngine(), GetDocID());
125 myShapesOperations = new GEOMImpl_IShapesOperations(GetEngine(), GetDocID());
126 myTransformOperations = new GEOMImpl_ITransformOperations(GetEngine(), GetDocID());
127 myBlocksOperations = new GEOMImpl_IBlocksOperations(GetEngine(), GetDocID());
128 my3DPrimOperations = new GEOMImpl_I3DPrimOperations(GetEngine(), GetDocID());
129 myLocalOperations = new GEOMImpl_ILocalOperations(GetEngine(), GetDocID());
130 myHealingOperations = new GEOMImpl_IHealingOperations(GetEngine(), GetDocID());
131 myGroupOperations = new GEOMImpl_IGroupOperations(GetEngine(), GetDocID());
134 //=============================================================================
138 //=============================================================================
139 GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations()
141 MESSAGE("GEOMImpl_IAdvancedOperations::~GEOMImpl_IAdvancedOperations");
142 delete myBasicOperations;
143 delete myBooleanOperations;
144 delete myShapesOperations;
145 delete myTransformOperations;
146 delete myBlocksOperations;
147 delete my3DPrimOperations;
148 delete myLocalOperations;
149 delete myHealingOperations;
150 delete myGroupOperations;
153 //=============================================================================
157 //=============================================================================
158 gp_Trsf GEOMImpl_IAdvancedOperations::GetPositionTrsf(double theL1, double theL2,
159 Handle(GEOM_Object) theP1,
160 Handle(GEOM_Object) theP2,
161 Handle(GEOM_Object) theP3)
163 // Old Local Coordinates System oldLCS
165 gp_Pnt P1(-theL1, 0, 0);
166 gp_Pnt P2(theL1, 0, 0);
167 gp_Pnt P3(0, 0, theL2);
169 gp_Dir oldX(gp_Vec(P1, P2));
170 gp_Dir oldZ(gp_Vec(P0, P3));
171 gp_Ax3 oldLCS(P0, oldZ, oldX);
173 // New Local Coordinates System newLCS
174 double LocX, LocY, LocZ;
175 gp_Pnt newP1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
176 gp_Pnt newP2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
177 gp_Pnt newP3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
178 LocX = (newP1.X() + newP2.X()) / 2.;
179 LocY = (newP1.Y() + newP2.Y()) / 2.;
180 LocZ = (newP1.Z() + newP2.Z()) / 2.;
181 gp_Pnt newO(LocX, LocY, LocZ);
183 gp_Dir newX(gp_Vec(newP1, newP2)); // P1P2 Vector
184 gp_Dir newZ(gp_Vec(newO, newP3)); // OP3 Vector
185 gp_Ax3 newLCS = gp_Ax3(newO, newZ, newX);
188 aTrsf.SetDisplacement(oldLCS, newLCS);
193 //=============================================================================
195 * CheckCompatiblePosition
198 //=============================================================================
199 bool GEOMImpl_IAdvancedOperations::CheckCompatiblePosition(double& theL1, double& theL2,
200 Handle(GEOM_Object) theP1,
201 Handle(GEOM_Object) theP2,
202 Handle(GEOM_Object) theP3,
206 gp_Pnt P1 = BRep_Tool::Pnt(TopoDS::Vertex(theP1->GetValue()));
207 gp_Pnt P2 = BRep_Tool::Pnt(TopoDS::Vertex(theP2->GetValue()));
208 gp_Pnt P3 = BRep_Tool::Pnt(TopoDS::Vertex(theP3->GetValue()));
210 double d12 = P1.Distance(P2);
211 double d13 = P1.Distance(P3);
212 double d23 = P2.Distance(P3);
213 // double d2 = newO.Distance(P3);
215 if (Abs(d12) <= Precision::Confusion()) {
216 SetErrorCode("Junctions points P1 and P2 are identical");
219 if (Abs(d13) <= Precision::Confusion()) {
220 SetErrorCode("Junctions points P1 and P3 are identical");
223 if (Abs(d23) <= Precision::Confusion()) {
224 SetErrorCode("Junctions points P2 and P3 are identical");
229 double newL1 = 0.5 * d12;
230 double newL2 = sqrt(pow(d13,2)-pow(newL1,2));
232 // theL1*(1-theTolerance) <= newL1 <= theL1*(1+theTolerance)
234 if (fabs(newL1 - theL1) > Precision::Approximation()) {
235 if ( (newL1 * (1 - theTolerance) -theL1 <= Precision::Approximation()) &&
236 (newL1 * (1 + theTolerance) -theL1 >= Precision::Approximation()) ) {
237 // std::cerr << "theL1 = newL1" << std::endl;
241 SetErrorCode("Dimension for main pipe (L1) is incompatible with new position");
247 // theL2*(1-theTolerance) <= newL2 <= theL2*(1+theTolerance)
249 if (fabs(newL2 - theL2) > Precision::Approximation()) {
250 if ( (newL2 * (1 - theTolerance) -theL2 <= Precision::Approximation()) &&
251 (newL2 * (1 + theTolerance) -theL2 >= Precision::Approximation()) ) {
255 SetErrorCode("Dimension for incident pipe (L2) is incompatible with new position");
265 //=============================================================================
267 * Generate the propagation groups of a Pipe T-Shape used for hexa mesh
269 //=============================================================================
270 bool GEOMImpl_IAdvancedOperations::MakeGroups(Handle(GEOM_Object) theShape, int shapeType,
271 double theR1, double theW1, double theL1,
272 double theR2, double theW2, double theL2,
273 double theH, double theW, double theRF,
274 Handle(TColStd_HSequenceOfTransient) theSeq,
279 if (theShape.IsNull()) return false;
281 TopoDS_Shape aShape = theShape->GetValue();
282 if (aShape.IsNull()) {
283 SetErrorCode("Shape is not defined");
287 gp_Trsf aTrsfInv = aTrsf.Inverted();
289 // int expectedGroups = 0;
290 // if (shapeType == TSHAPE_BASIC)
291 // if (Abs(theR2+theW2-theR1-theW1) <= Precision::Approximation())
292 // expectedGroups = 10;
294 // expectedGroups = 11;
295 // else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET)
296 // expectedGroups = 12;
298 double aR1Ext = theR1 + theW1;
299 double aR2Ext = theR2 + theW2;
301 /////////////////////////
302 //// Groups of Faces ////
303 /////////////////////////
306 // Comment the following lines when GetInPlace bug is solved
308 // Workaround of GetInPlace bug
309 // Create a bounding box that fits the shape
310 Handle(GEOM_Object) aBox = my3DPrimOperations->MakeBoxDXDYDZ(2*theL1, 2*aR1Ext, aR1Ext+theL2);
311 aBox->GetLastFunction()->SetDescription("");
312 myTransformOperations->TranslateDXDYDZ(aBox, -theL1, -aR1Ext, -aR1Ext);
313 aBox->GetLastFunction()->SetDescription("");
314 // Apply transformation to box
315 BRepBuilderAPI_Transform aTransformationBox(aBox->GetValue(), aTrsf, Standard_False);
316 TopoDS_Shape aBoxShapeTrsf = aTransformationBox.Shape();
317 aBox->GetLastFunction()->SetValue(aBoxShapeTrsf);
319 // Get the shell of the box
320 Handle(GEOM_Object) aShell = Handle(GEOM_Object)::DownCast
321 (myShapesOperations->MakeExplode(aBox, TopAbs_SHELL, true)->Value(1));
322 aBox->GetLastFunction()->SetDescription("");
323 aShell->GetLastFunction()->SetDescription("");
324 // Get the common shapes between shell and shape
325 Handle(GEOM_Object) aCommonCompound = myBooleanOperations->MakeBoolean (theShape, aShell, 1); // MakeCommon
326 if (aCommonCompound.IsNull()) {
327 SetErrorCode(myBooleanOperations->GetErrorCode());
330 aCommonCompound->GetLastFunction()->SetDescription("");
331 // Explode the faces of common shapes => 3 faces
332 Handle(TColStd_HSequenceOfTransient) aCommonFaces =
333 myShapesOperations->MakeExplode(aCommonCompound, TopAbs_FACE, true);
334 aCommonCompound->GetLastFunction()->SetDescription("");
335 std::list<Handle(GEOM_Object)> aCompoundOfFacesList;
337 for (int i=0 ; i<= aCommonFaces->Length()-4 ; i+=4) {
338 std::list<Handle(GEOM_Object)> aFacesList;
339 for (int j = 1 ; j <= 4 ; j++) {
340 Handle(GEOM_Object) aFace = Handle(GEOM_Object)::DownCast(aCommonFaces->Value(i+j)); // Junction faces
341 if (!aFace.IsNull()) {
342 aFace->GetLastFunction()->SetDescription("");
343 aFacesList.push_back(aFace);
346 Handle(GEOM_Object) aCompoundOfFaces = myShapesOperations->MakeCompound(aFacesList);
347 if (!aCompoundOfFaces.IsNull()) {
348 aCompoundOfFaces->GetLastFunction()->SetDescription("");
349 aCompoundOfFacesList.push_back(aCompoundOfFaces);
353 if (aCompoundOfFacesList.size() == 3) {
354 Handle(GEOM_Object) aPln1 = aCompoundOfFacesList.front();
355 aCompoundOfFacesList.pop_front();
356 Handle(GEOM_Object) aPln2 = aCompoundOfFacesList.front();
357 aCompoundOfFacesList.pop_front();
358 Handle(GEOM_Object) aPln3 = aCompoundOfFacesList.front();
359 aCompoundOfFacesList.pop_front();
364 // Uncomment the following lines when GetInPlace bug is solved
366 // Handle(GEOM_Object) aP1 = myBasicOperations->MakePointXYZ(-theL1, 0, 0);
367 // Handle(GEOM_Object) aP2 = myBasicOperations->MakePointXYZ(-0, 0, theL2);
368 // Handle(GEOM_Object) aP3 = myBasicOperations->MakePointXYZ(theL1, 0, 0);
369 // aP1->GetLastFunction()->SetDescription("");
370 // aP2->GetLastFunction()->SetDescription("");
371 // aP3->GetLastFunction()->SetDescription("");
372 // Handle(GEOM_Object) aV1 = myBasicOperations->MakeVectorDXDYDZ(-1, 0, 0);
373 // Handle(GEOM_Object) aV2 = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
374 // Handle(GEOM_Object) aV3 = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
375 // aV1->GetLastFunction()->SetDescription("");
376 // aV2->GetLastFunction()->SetDescription("");
377 // aV3->GetLastFunction()->SetDescription("");
378 // Handle(GEOM_Object) aPln1 = myBasicOperations->MakePlanePntVec(aP1, aV1, 2*(aR1Ext+theL2));
379 // Handle(GEOM_Object) aPln2 = myBasicOperations->MakePlanePntVec(aP2, aV2, 2*(aR2Ext));
380 // Handle(GEOM_Object) aPln3 = myBasicOperations->MakePlanePntVec(aP3, aV3, 2*(aR1Ext+theL2));
381 // aPln1->GetLastFunction()->SetDescription("");
382 // aPln2->GetLastFunction()->SetDescription("");
383 // aPln3->GetLastFunction()->SetDescription("");
385 // BRepBuilderAPI_Transform aTransformation1(aPln1->GetValue(), aTrsf, Standard_False);
386 // TopoDS_Shape aTrsf_Shape1 = aTransformation1.Shape();
387 // aPln1->GetLastFunction()->SetValue(aTrsf_Shape1);
388 // BRepBuilderAPI_Transform aTransformation2(aPln2->GetValue(), aTrsf, Standard_False);
389 // TopoDS_Shape aTrsf_Shape2 = aTransformation2.Shape();
390 // aPln2->GetLastFunction()->SetValue(aTrsf_Shape2);
391 // BRepBuilderAPI_Transform aTransformation3(aPln3->GetValue(), aTrsf, Standard_False);
392 // TopoDS_Shape aTrsf_Shape3 = aTransformation3.Shape();
393 // aPln3->GetLastFunction()->SetValue(aTrsf_Shape3);
397 Handle(GEOM_Object) junctionFaces1 = myShapesOperations->GetInPlace(theShape, aPln1);
398 if (junctionFaces1.IsNull())
399 junctionFaces1 = myShapesOperations->GetShapesOnShapeAsCompound
400 (aPln1, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
401 if (!junctionFaces1.IsNull()) {
402 junctionFaces1->GetLastFunction()->SetDescription("");
403 junctionFaces1->SetName("JUNCTION_FACE_1");
404 theSeq->Append(junctionFaces1);
407 SetErrorCode("Junction face 1 not found");
408 // theSeq->Append(aPln1);
411 Handle(GEOM_Object) junctionFaces2 = myShapesOperations->GetInPlace(theShape, aPln2);
412 if (junctionFaces2.IsNull())
413 junctionFaces2 = myShapesOperations->GetShapesOnShapeAsCompound
414 (aPln2, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
415 if (!junctionFaces2.IsNull()) {
416 junctionFaces2->GetLastFunction()->SetDescription("");
417 junctionFaces2->SetName("JUNCTION_FACE_2");
418 theSeq->Append(junctionFaces2);
421 SetErrorCode("Junction face 2 not found");
422 // theSeq->Append(aPln2);
425 Handle(GEOM_Object) junctionFaces3 = myShapesOperations->GetInPlace(theShape, aPln3);
426 if (junctionFaces3.IsNull())
427 junctionFaces3 = myShapesOperations->GetShapesOnShapeAsCompound
428 (aPln3, theShape, TopAbs_FACE, GEOMAlgo_ST_ONIN);
429 if (!junctionFaces3.IsNull()) {
430 junctionFaces3->GetLastFunction()->SetDescription("");
431 junctionFaces3->SetName("JUNCTION_FACE_3");
432 theSeq->Append(junctionFaces3);
435 SetErrorCode("Junction face 3 not found");
436 // theSeq->Append(aPln3);
439 // Comment the following lines when GetInPlace bug is solved
444 /////////////////////////
445 //// Groups of Edges ////
446 /////////////////////////
447 // Result of propagate
449 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
451 TCollection_AsciiString theDesc = aFunction->GetDescription();
452 Handle(TColStd_HSequenceOfTransient) aSeqPropagate = myBlocksOperations->Propagate(theShape);
453 if (aSeqPropagate.IsNull() || aSeqPropagate->Length() == 0) {
454 SetErrorCode("Propagation groups not found");
457 Standard_Integer aNbGroups = aSeqPropagate->Length();
458 // Recover previous description to get rid of Propagate dump
459 aFunction->SetDescription(theDesc);
461 #ifdef FIND_GROUPS_BY_POINTS
462 // BEGIN: new groups search
469 // g / ''..| | |..'' \
471 // .---.--'.. | | | ..'--.---.
472 // |a \ '''...........''' / |
473 // |-------\------' | '------/-------.
478 // ._________________|_________________.
484 // |-----------------|-----------------|
486 // '-----------------'-----------------'
489 // "Thickness" group (a)
490 gp_Pnt aPntA (-theL1, 0, theR1 + theW1/2.);
491 aPntA.Transform(aTrsf);
492 BRepBuilderAPI_MakeVertex mkVertexA (aPntA);
493 TopoDS_Vertex aVertA = TopoDS::Vertex(mkVertexA.Shape());
494 TopoDS_Shape anEdgeA = GEOMUtils::GetEdgeNearPoint(aShape, aVertA);
496 // "Circular quarter of pipe" group (b)
497 gp_Pnt aPntB (-theL1, -aR1Ext * sin(M_PI/4.), -aR1Ext * sin(M_PI/4.));
498 aPntB.Transform(aTrsf);
499 BRepBuilderAPI_MakeVertex mkVertexB (aPntB);
500 TopoDS_Vertex aVertB = TopoDS::Vertex(mkVertexB.Shape());
501 TopoDS_Shape anEdgeB = GEOMUtils::GetEdgeNearPoint(aShape, aVertB);
503 // "Circular quarter of pipe" group (c)
504 gp_Pnt aPntC (-theL1, -aR1Ext * sin(M_PI/4.), aR1Ext * sin(M_PI/4.));
505 aPntC.Transform(aTrsf);
506 BRepBuilderAPI_MakeVertex mkVertexC (aPntC);
507 TopoDS_Vertex aVertC = TopoDS::Vertex(mkVertexC.Shape());
508 TopoDS_Shape anEdgeC = GEOMUtils::GetEdgeNearPoint(aShape, aVertC);
510 // "Main pipe half length" group (d)
511 gp_Pnt aPntD (-theL1/2., 0, -aR1Ext);
512 aPntD.Transform(aTrsf);
513 BRepBuilderAPI_MakeVertex mkVertexD (aPntD);
514 TopoDS_Vertex aVertD = TopoDS::Vertex(mkVertexD.Shape());
515 TopoDS_Shape anEdgeD = GEOMUtils::GetEdgeNearPoint(aShape, aVertD);
517 // "Incident pipe half length" group (e)
518 double aTol10 = Precision::Confusion() * 10.;
519 gp_Pnt aPntE (-aR2Ext, 0, theL2 - aTol10);
520 aPntE.Transform(aTrsf);
521 BRepBuilderAPI_MakeVertex mkVertexE (aPntE);
522 TopoDS_Vertex aVertE = TopoDS::Vertex(mkVertexE.Shape());
523 TopoDS_Shape anEdgeE = GEOMUtils::GetEdgeNearPoint(aShape, aVertE);
525 // "Flange" group (f)
526 double aFx = - aR2Ext - aTol10;
527 if (shapeType == TSHAPE_CHAMFER)
529 else if (shapeType == TSHAPE_FILLET)
531 gp_Pnt aPntF (aFx, 0, aR1Ext);
532 aPntF.Transform(aTrsf);
533 BRepBuilderAPI_MakeVertex mkVertexF (aPntF);
534 TopoDS_Vertex aVertF = TopoDS::Vertex(mkVertexF.Shape());
535 TopoDS_Shape anEdgeF = GEOMUtils::GetEdgeNearPoint(aShape, aVertF);
537 // "Chamfer or Fillet" group (g)
538 TopoDS_Shape anEdgeG;
539 if (shapeType == TSHAPE_CHAMFER) {
540 gp_Pnt aPntG (-aR2Ext - theW/2., 0, aR1Ext + theH/2.);
541 aPntG.Transform(aTrsf);
542 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
543 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
544 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
546 else if (shapeType == TSHAPE_FILLET) {
547 gp_Pnt aPntG (-aR2Ext - theRF/2., 0, aR1Ext + theRF/2.);
548 aPntG.Transform(aTrsf);
549 BRepBuilderAPI_MakeVertex mkVertexG (aPntG);
550 TopoDS_Vertex aVertG = TopoDS::Vertex(mkVertexG.Shape());
551 anEdgeG = GEOMUtils::GetEdgeNearPoint(aShape, aVertG);
554 for (int i = 1 ; i <= aNbGroups; i++) {
555 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
559 TopoDS_Shape aGroupShape = aGroup->GetValue();
560 TopTools_IndexedMapOfShape anEdgesMap;
561 TopExp::MapShapes(aGroupShape, TopAbs_EDGE, anEdgesMap);
563 if (anEdgesMap.Contains(anEdgeA)) { // a
564 aGroup->SetName("THICKNESS");
565 theSeq->Append(aGroup);
567 else if (anEdgesMap.Contains(anEdgeB)) { // b
568 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
569 theSeq->Append(aGroup);
571 else if (anEdgesMap.Contains(anEdgeC)) { // c
572 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
573 theSeq->Append(aGroup);
575 else if (anEdgesMap.Contains(anEdgeD)) { // d
576 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
577 theSeq->Append(aGroup);
579 else if (anEdgesMap.Contains(anEdgeE)) { // e
580 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
581 theSeq->Append(aGroup);
583 else if (anEdgesMap.Contains(anEdgeF)) { // f
584 aGroup->SetName("FLANGE");
585 theSeq->Append(aGroup);
587 else if (shapeType == TSHAPE_CHAMFER) { // g
588 if (anEdgesMap.Contains(anEdgeG)) {
589 aGroup->SetName("CHAMFER");
590 theSeq->Append(aGroup);
593 else if (shapeType == TSHAPE_FILLET) { // g
594 if (anEdgesMap.Contains(anEdgeG)) {
595 aGroup->SetName("FILLET");
596 theSeq->Append(aGroup);
602 // END: new groups search
605 bool circularFoundAndAdded = false;
606 bool circularFound10 = false;
607 bool incidentPipeFound = false;
608 bool mainPipeFound = false;
609 bool mainPipeFoundAndAdded = false;
610 bool radialFound =false;
611 bool flangeFound = false;
612 bool flangeFoundAndAdded = false;
613 bool chamferOrFilletFound = false;
615 for (int i = 1 ; i <= aNbGroups; i++) {
618 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(aSeqPropagate->Value(i));
622 TopoDS_Shape aGroupShape = aGroup->GetValue();
623 BRepBuilderAPI_Transform aTransformationShapeInv (aGroupShape, aTrsfInv, Standard_False);
624 TopoDS_Shape aGroupShapeTrsfInv = aTransformationShapeInv.Shape();
626 TopTools_IndexedMapOfShape anEdgesMap;
627 TopExp::MapShapes(aGroupShapeTrsfInv,TopAbs_EDGE, anEdgesMap);
628 Standard_Integer nbEdges = anEdgesMap.Extent();
630 if (shapeType == TSHAPE_BASIC) {
631 if ((nbEdges >= 21) || /*R1Ext = R2Ext*/(nbEdges == 17)) { // 17, 17+8*{1,2,3}, 21, 21+8*{1,2,3}
633 aGroup->SetName("THICKNESS");
635 else if (nbEdges == 6) {
636 if (!circularFoundAndAdded) {
637 circularFoundAndAdded = true;
639 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
642 else if (nbEdges == 8) {
643 incidentPipeFound = true;
644 mainPipeFound = false;
648 TopExp_Explorer Ex(aGroupShapeTrsfInv,TopAbs_VERTEX);
650 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
651 double x=aP.X(), y=aP.Y(), z=aP.Z();
654 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
655 (Abs(y) > aR2Ext + Precision::Confusion())) {
656 incidentPipeFound = false;
659 if ( z < -Precision::Confusion()) {
660 // length of main pipe
661 mainPipeFound = true;
662 if (!mainPipeFoundAndAdded) {
663 mainPipeFoundAndAdded = true;
665 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
669 else if (Abs(x) > (theL1-Precision::Confusion())) {
670 // discretisation circulaire
672 if (!circularFoundAndAdded) {
673 circularFoundAndAdded = true;
675 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
680 if (incidentPipeFound) {
682 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
684 if (!addGroup && (!incidentPipeFound &&
688 // Flange (collerette)
691 aGroup->SetName("FLANGE");
697 else if (shapeType == TSHAPE_CHAMFER || shapeType == TSHAPE_FILLET) {
698 if (nbEdges >= 25) { // 25, 25+8, 25+16, 25+24
700 aGroup->SetName("THICKNESS");
702 else if ((nbEdges == 10) || (nbEdges == 6)) {
703 if (!circularFoundAndAdded) {
705 circularFoundAndAdded = true;
706 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
708 circularFound10 = true;
711 else if (!circularFound10 && nbEdges == 10) {
712 circularFound10 = true;
714 aGroup->SetName("CIRCULAR_QUARTER_PIPE");
717 else if (nbEdges == 8) {
718 incidentPipeFound = true;
719 mainPipeFound = true;
722 bool isNearZ0 = false;
723 bool isBelowZ0 = false;
725 TopExp_Explorer Ex (aGroupShapeTrsfInv,TopAbs_VERTEX);
727 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
728 double x=aP.X(), y=aP.Y(), z=aP.Z();
730 // tuy_princ_long_avant & tuy_princ_long_apres
731 //bool isMain = (((z < Precision::Confusion()) || (x < Precision::Confusion())) &&
732 // ((y <= aR1Ext + Precision::Confusion()) ||
733 // (y <= -(aR1Ext + Precision::Confusion())) ||
734 // (y <= theR1 + Precision::Confusion()) ||
735 // (y == -(theR1 + Precision::Confusion()))));
736 bool isMain = ((z < Precision::Confusion() || x < Precision::Confusion()) &&
737 (fabs(y) > theR1 - Precision::Confusion() ||
738 fabs(y) < Precision::Confusion()));
741 mainPipeFound = false;
745 //if (z < Precision::Confusion() && !isMain) {
746 // flangeFound = true;
747 // if (!flangeFoundAndAdded) {
748 // flangeFoundAndAdded = true;
750 // aGroup->SetName("FLANGE");
753 if (fabs(z) < Precision::Confusion()) isNearZ0 = true;
754 if (z < - Precision::Confusion()) isBelowZ0 = true;
757 if ((Abs(x) > aR2Ext + Precision::Confusion()) ||
758 (Abs(y) > aR2Ext + Precision::Confusion())) {
759 incidentPipeFound = false;
765 aGroup->SetName("HALF_LENGTH_MAIN_PIPE");
767 if (incidentPipeFound) {
769 aGroup->SetName("HALF_LENGTH_INCIDENT_PIPE");
771 if (isNearZ0 && !isBelowZ0) {
773 if (!flangeFoundAndAdded) {
774 flangeFoundAndAdded = true;
776 aGroup->SetName("FLANGE");
779 if (!addGroup && (!incidentPipeFound &&
782 !chamferOrFilletFound)) {
784 chamferOrFilletFound = true;
785 if (shapeType == TSHAPE_CHAMFER)
786 aGroup->SetName("CHAMFER");
788 aGroup->SetName("FILLET");
794 // Add group to the list
796 theSeq->Append(aGroup);
804 //=============================================================================
806 * Return faces that are laying on surface.
808 //=============================================================================
809 bool GEOMImpl_IAdvancedOperations::GetFacesOnSurf
810 (const TopoDS_Shape &theShape,
811 const Handle_Geom_Surface& theSurface,
812 const Standard_Real theTolerance,
813 TopTools_ListOfShape &theFaces)
815 GEOMAlgo_FinderShapeOn1 aFinder;
817 aFinder.SetShape(theShape);
818 aFinder.SetTolerance(theTolerance);
819 aFinder.SetSurface(theSurface);
820 aFinder.SetShapeType(TopAbs_FACE);
821 aFinder.SetState(GEOMAlgo_ST_ON);
823 // Sets the minimal number of inner points for the faces that do not have own
824 // inner points at all (for e.g. rectangular planar faces have just 2 triangles).
826 aFinder.SetNbPntsMin(3);
827 // Sets the maximal number of inner points for edges or faces.
828 // It is usefull for the cases when this number is very big (e.g =2000) to improve
829 // the performance. If this value =0, all inner points will be taken into account.
831 aFinder.SetNbPntsMax(100);
834 // Interprete results
835 Standard_Integer iErr = aFinder.ErrorStatus();
836 // the detailed description of error codes is in GEOMAlgo_FinderShapeOn1.cxx
838 MESSAGE(" iErr : " << iErr);
839 TCollection_AsciiString aMsg (" iErr : ");
840 aMsg += TCollection_AsciiString(iErr);
844 Standard_Integer iWrn = aFinder.WarningStatus();
845 // the detailed description of warning codes is in GEOMAlgo_FinderShapeOn1.cxx
847 MESSAGE(" *** iWrn : " << iWrn);
850 const TopTools_ListOfShape &aListRes = aFinder.Shapes(); // the result
851 TopTools_ListIteratorOfListOfShape anIter (aListRes);
853 for (; anIter.More(); anIter.Next()) {
854 theFaces.Append(anIter.Value());
860 //=============================================================================
862 * Creates and returns conical face.
864 //=============================================================================
865 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakeConicalFace
866 (const gp_Ax2 &theAxis,
867 const double theRadius,
868 const double theRadiusThin,
869 const double theHeight,
870 const gp_Trsf &theTrsf)
872 BRepPrimAPI_MakeCone aMkCone (theAxis, theRadius, theRadiusThin, theHeight);
873 TopoDS_Shape aResult;
876 if (aMkCone.IsDone()) {
877 TopExp_Explorer anExp(aMkCone.Shape(), TopAbs_FACE);
879 for (; anExp.More(); anExp.Next()) {
880 TopoDS_Face aFace = TopoDS::Face(anExp.Current());
882 if (aFace.IsNull() == Standard_False) {
883 BRepAdaptor_Surface anAdaptor(aFace, Standard_False);
885 if (anAdaptor.GetType() == GeomAbs_Cone) {
886 // This is a conical face. Transform and return it.
887 BRepBuilderAPI_Transform aTransf(aFace, theTrsf, Standard_False);
889 aResult = aTransf.Shape();
899 //=============================================================================
901 * Generate the internal group of a Pipe T-Shape
903 //=============================================================================
904 bool GEOMImpl_IAdvancedOperations::MakeInternalGroup
905 (const Handle(GEOM_Object) &theShape,
906 const double theR1, const double theLen1,
907 const double theR2, const double theLen2,
908 const double theRL, double theTransLenL,
909 const double theRR, double theTransLenR,
910 const double theRI, double theTransLenI,
911 const Handle(TColStd_HSequenceOfTransient) &theSeq,
912 const gp_Trsf &theTrsf)
916 if (theShape.IsNull()) {
920 TopoDS_Shape aShape = theShape->GetValue();
922 if (aShape.IsNull()) {
923 SetErrorCode("Shape is not defined");
928 Standard_Real aMaxTol = -RealLast();
929 TopExp_Explorer anExp(aShape, TopAbs_VERTEX);
931 for (; anExp.More(); anExp.Next()) {
932 TopoDS_Vertex aVertex = TopoDS::Vertex(anExp.Current());
934 if (aVertex.IsNull() == Standard_False) {
935 const Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
937 if (aTol > aMaxTol) {
943 // Construct internal surfaces.
944 Standard_Integer i = 0;
945 const Standard_Integer aMaxNbSurf = 5;
946 Handle(Geom_Surface) aSurface[aMaxNbSurf];
947 TopTools_ListOfShape aConicalFaces;
948 Standard_Real aTolConf = Precision::Confusion();
950 // 1. Construct the internal surface of main pipe.
951 gp_Ax2 anAxis1 (gp::Origin(), gp::DX(), gp::DZ());
952 gp_Ax2 anAxis2 (gp::Origin(), gp::DZ(), gp::DX());
954 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theR1);
956 // 2. Construct the internal surface of incident pipe.
957 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theR2);
959 // 3. Construct the internal surface of left reduction pipe.
960 if (theRL > aTolConf) {
961 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRL);
963 if (theTransLenL > aTolConf) {
964 // 3.1. Construct the internal surface of left transition pipe.
965 gp_Pnt aPLeft (-theLen1, 0., 0.);
966 gp_Ax2 anAxisLeft (aPLeft, -gp::DX(), gp::DZ());
967 TopoDS_Shape aConeLeft =
968 MakeConicalFace(anAxisLeft, theR1, theRL, theTransLenL, theTrsf);
970 if (aConeLeft.IsNull() == Standard_False) {
971 aConicalFaces.Append(aConeLeft);
976 // 4. Construct the internal surface of right reduction pipe.
977 if (theRR > aTolConf) {
978 // There is no need to construct another cylinder of the same radius. Skip it.
979 if (Abs(theRR - theRL) > aTolConf) {
980 aSurface[i++] = new Geom_CylindricalSurface(anAxis1, theRR);
983 if (theTransLenL > aTolConf) {
984 // 4.1. Construct the internal surface of right transition pipe.
985 gp_Pnt aPRight (theLen1, 0., 0.);
986 gp_Ax2 anAxisRight (aPRight, gp::DX(), gp::DZ());
987 TopoDS_Shape aConeRight =
988 MakeConicalFace(anAxisRight, theR1, theRR, theTransLenR, theTrsf);
990 if (aConeRight.IsNull() == Standard_False) {
991 aConicalFaces.Append(aConeRight);
996 // 5. Construct the internal surface of incident reduction pipe.
997 if (theRI > aTolConf) {
998 aSurface[i++] = new Geom_CylindricalSurface(anAxis2, theRI);
1000 if (theTransLenI > aTolConf) {
1001 // 5.1. Construct the internal surface of incident transition pipe.
1002 gp_Pnt aPInci (0., 0., theLen2);
1003 gp_Ax2 anAxisInci (aPInci, gp::DZ(), gp::DX());
1004 TopoDS_Shape aConeInci =
1005 MakeConicalFace(anAxisInci, theR2, theRI, theTransLenI, theTrsf);
1007 if (aConeInci.IsNull() == Standard_False) {
1008 aConicalFaces.Append(aConeInci);
1013 // Get faces that are laying on cylindrical surfaces.
1014 TopTools_ListOfShape aFaces;
1015 gp_Trsf anInvTrsf = theTrsf.Inverted();
1017 for (i = 0; i < aMaxNbSurf; i++) {
1018 if (aSurface[i].IsNull()) {
1022 aSurface[i]->Transform(theTrsf);
1024 TopTools_ListOfShape aLocalFaces;
1026 if (!GetFacesOnSurf(aShape, aSurface[i], aMaxTol, aLocalFaces)) {
1031 // Check if the result contains outer cylinders.
1032 // It is required for main and incident pipes.
1033 TopTools_ListIteratorOfListOfShape anIter(aLocalFaces);
1035 while (anIter.More()) {
1036 TopExp_Explorer anExp(anIter.Value(), TopAbs_VERTEX);
1037 Standard_Boolean isInside = Standard_False;
1039 // Get a vertex from this shape
1041 TopoDS_Vertex aVtx = TopoDS::Vertex(anExp.Current());
1043 if (aVtx.IsNull() == Standard_False) {
1044 gp_Pnt aPnt = BRep_Tool::Pnt(aVtx);
1046 aPnt.Transform(anInvTrsf);
1049 // Check if the point is inside the main pipe.
1050 isInside = (Abs(aPnt.X()) <= theLen1);
1052 // Check if the point is inside the incident pipe.
1053 isInside = (aPnt.Z() <= theLen2);
1062 // Remove this face.
1063 aLocalFaces.Remove(anIter);
1068 aFaces.Append(aLocalFaces);
1071 // Get faces that are laying on conical faces.
1072 if (aConicalFaces.IsEmpty() == Standard_False) {
1073 Handle(GEOM_Object) aCone =
1074 GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1075 Handle(GEOM_Function) aFunction =
1076 aCone->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1077 TopTools_ListIteratorOfListOfShape aFIter(aConicalFaces);
1078 Handle(GEOM_Object) aConeFromShape;
1080 for (; aFIter.More(); aFIter.Next()) {
1081 aFunction->SetValue(aFIter.Value());
1082 aConeFromShape = myShapesOperations->GetInPlace(theShape, aCone);
1084 if (aConeFromShape.IsNull() == Standard_False) {
1085 aConeFromShape->GetLastFunction()->SetDescription("");
1086 TopoDS_Shape aConeFaces = aConeFromShape->GetValue();
1087 TopExp_Explorer anExp(aConeFaces, TopAbs_FACE);
1089 for (; anExp.More(); anExp.Next()) {
1090 TopoDS_Face aConeFace = TopoDS::Face(anExp.Current());
1092 if (aConeFace.IsNull() == Standard_False) {
1093 aFaces.Append(aConeFace);
1100 // Create a group of internal faces.
1101 if (aFaces.IsEmpty() == Standard_False) {
1102 Handle(GEOM_Object) aGroup = myGroupOperations->CreateGroup(theShape, TopAbs_FACE);
1104 if (aGroup.IsNull() == Standard_False) {
1105 aGroup->GetLastFunction()->SetDescription("");
1106 aGroup->SetName("INTERNAL_FACES");
1108 TopTools_IndexedMapOfShape anIndices;
1109 Handle(TColStd_HSequenceOfInteger) aSeqIDs = new TColStd_HSequenceOfInteger;
1111 TopExp::MapShapes(aShape, anIndices);
1113 TopTools_ListIteratorOfListOfShape anIter(aFaces);
1115 for (; anIter.More(); anIter.Next()) {
1116 const TopoDS_Shape &aFace = anIter.Value();
1117 const Standard_Integer anIndex = anIndices.FindIndex(aFace);
1120 aSeqIDs->Append(anIndex);
1124 myGroupOperations->UnionIDs(aGroup, aSeqIDs);
1125 aGroup->GetLastFunction()->SetDescription("");
1126 theSeq->Append(aGroup);
1135 bool GEOMImpl_IAdvancedOperations::MakePipeTShapePartition(Handle(GEOM_Object) theShape,
1136 double theR1, double theW1, double theL1,
1137 double theR2, double theW2, double theL2,
1138 double theH, double theW,
1139 double theRF, bool isNormal)
1143 // Build tools for partition operation:
1144 // 1 face and 2 planes
1146 Handle(GEOM_Object) arete_intersect_int;
1147 Handle(GEOM_Object) wire_t, wire_t2, face_t, face_t2;
1148 Handle(GEOM_Object) chan_racc;
1149 Handle(GEOM_Object) vi1, vi2;
1150 Handle(GEOM_Object) Te3;
1153 #if OCC_VERSION_LARGE > 0x06010000
1156 Handle(GEOM_Object) Vector_Z = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1157 Vector_Z->GetLastFunction()->SetDescription("");
1160 double aSize = 2*(theL1 + theL2);
1161 double aR1Ext = theR1 + theW1;
1162 double aR2Ext = theR2 + theW2;
1163 double theVertCylinderRadius = aR2Ext + theW + theRF;
1164 double theHoriCylinderRadius = aR1Ext + theH + theRF;
1166 // Common edges on internal cylinder
1167 Handle(GEOM_Object) box_i = my3DPrimOperations->MakeBoxDXDYDZ(theR2, theR2, theR1);
1168 box_i->GetLastFunction()->SetDescription("");
1169 box_i = myTransformOperations->TranslateDXDYDZ(box_i, -theR2, -theR2, 0);
1170 box_i->GetLastFunction()->SetDescription("");
1172 Handle(GEOM_Function) aFunction = theShape->GetLastFunction();
1173 TCollection_AsciiString theDesc = aFunction->GetDescription();
1174 Handle(TColStd_HSequenceOfTransient) edges_i =
1175 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1176 // Recover previous description to get rid of Propagate dump
1177 aFunction->SetDescription(theDesc);
1178 if (edges_i.IsNull() || edges_i->Length() == 0) {
1179 SetErrorCode("Internal edges not found");
1182 for (int i=1; i<=edges_i->Length();i++) {
1183 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_i->Value(i));
1184 anObj->GetLastFunction()->SetDescription("");
1186 arete_intersect_int = Handle(GEOM_Object)::DownCast(edges_i->Value(1));
1188 // search for vertices located on both internal pipes
1189 aFunction = theShape->GetLastFunction();
1190 theDesc = aFunction->GetDescription();
1191 Handle(TColStd_HSequenceOfTransient) vertices_i =
1192 myShapesOperations->GetShapesOnBox(box_i, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1193 // Recover previous description to get rid of Propagate dump
1194 aFunction->SetDescription(theDesc);
1195 if (vertices_i.IsNull() || vertices_i->Length() == 0) {
1196 SetErrorCode("Internal vertices not found");
1200 for (int i = 1; i <= vertices_i->Length(); i++) {
1201 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_i->Value(i));
1202 v->GetLastFunction()->SetDescription("");
1203 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1204 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1205 // std::cout << "Coords: " << aP.X() << ", " << aP.Y() << ", " << aP.Z() << std::endl;
1206 if (Abs(aP.X()) <= Precision::Confusion()) {
1207 if (Abs(aP.Y()) - theR1 <= Precision::Confusion()) {
1210 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1211 if (Abs(aP.X()) - theR1 <= Precision::Confusion()) {
1217 std::list<Handle(GEOM_Object)> theShapes;
1220 Handle(GEOM_Object) ve1, ve2;
1222 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ(aR2Ext, aR2Ext, aR1Ext);
1223 box_e->GetLastFunction()->SetDescription("");
1224 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -aR2Ext, -aR2Ext, 0);
1225 box_e->GetLastFunction()->SetDescription("");
1226 // Common edges on external cylinder
1227 aFunction = theShape->GetLastFunction();
1228 theDesc = aFunction->GetDescription();
1229 Handle(TColStd_HSequenceOfTransient) edges_e =
1230 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
1231 // Recover previous description to get rid of Propagate dump
1232 aFunction->SetDescription(theDesc);
1233 if (edges_e.IsNull() || edges_e->Length() == 0) {
1234 SetErrorCode("External edges not found");
1237 for (int i=1; i<=edges_e->Length();i++) {
1238 Handle(GEOM_Object) anObj = Handle(GEOM_Object)::DownCast(edges_e->Value(i));
1239 anObj->GetLastFunction()->SetDescription("");
1242 // search for vertices located on both external pipes
1243 aFunction = theShape->GetLastFunction();
1244 theDesc = aFunction->GetDescription();
1245 Handle(TColStd_HSequenceOfTransient) vertices_e =
1246 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1247 // Recover previous description to get rid of Propagate dump
1248 aFunction->SetDescription(theDesc);
1249 if (vertices_e.IsNull() || vertices_e->Length() == 0) {
1250 SetErrorCode("External vertices not found");
1254 for (int i = 1; i <= vertices_e->Length(); i++) {
1255 Handle(GEOM_Object) v = Handle(GEOM_Object)::DownCast(vertices_e->Value(i));
1256 v->GetLastFunction()->SetDescription("");
1257 TopoDS_Vertex aVertex = TopoDS::Vertex(v->GetValue());
1258 gp_Pnt aP = BRep_Tool::Pnt(aVertex);
1259 // std::cout << "Coords: " << aP.X() << ", " << aP.Y() << ", " << aP.Z() << std::endl;
1260 if (Abs(aP.X()) <= Precision::Confusion()) {
1261 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1264 } else if (Abs(aP.Y()) <= Precision::Confusion()) {
1265 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1269 if ( !ve1.IsNull() && !ve2.IsNull())
1272 Handle(GEOM_Object) edge_e1, edge_e2;
1274 edge_e1 = myBasicOperations->MakeLineTwoPnt(ve1, vi1);
1275 if (edge_e1.IsNull()) {
1276 SetErrorCode("Edge 1 could not be built");
1280 edge_e2 = myBasicOperations->MakeLineTwoPnt(ve2, vi2);
1281 if (edge_e2.IsNull()) {
1282 SetErrorCode("Edge 2 could not be built");
1286 edge_e1->GetLastFunction()->SetDescription("");
1287 edge_e2->GetLastFunction()->SetDescription("");
1289 std::list<Handle(GEOM_Object)> edge_e_elist;
1290 edge_e_elist.push_back(arete_intersect_int);
1291 edge_e_elist.push_back(edge_e1);
1292 edge_e_elist.push_back(Handle(GEOM_Object)::DownCast(edges_e->Value(1)));
1293 edge_e_elist.push_back(edge_e2);
1294 wire_t = myShapesOperations->MakeWire(edge_e_elist, 1e-7);
1295 if (wire_t.IsNull()) {
1296 SetErrorCode("Impossible to build wire");
1299 wire_t->GetLastFunction()->SetDescription("");
1300 face_t = myShapesOperations->MakeFace(wire_t, false);
1301 if (face_t.IsNull()) {
1302 SetErrorCode("Impossible to build face");
1305 face_t->GetLastFunction()->SetDescription("");
1307 theShapes.push_back(theShape);
1308 theShapes.push_back(vi1);
1309 theShapes.push_back(vi2);
1310 theShapes.push_back(ve1);
1311 theShapes.push_back(ve2);
1312 theShapes.push_back(edge_e1);
1313 theShapes.push_back(edge_e2);
1314 theShapes.push_back(wire_t);
1315 theShapes.push_back(face_t);
1318 Handle(GEOM_Object) P1, P2, P3, P4, P5, P6;
1319 int idP1, idP2, idP3, idP4;
1322 std::vector<int> LX;
1323 std::vector<int> LY;
1324 Handle(GEOM_Object) box_e = my3DPrimOperations->MakeBoxDXDYDZ
1325 (theVertCylinderRadius, theVertCylinderRadius, theHoriCylinderRadius);
1326 box_e->GetLastFunction()->SetDescription("");
1327 box_e = myTransformOperations->TranslateDXDYDZ
1328 (box_e, -theVertCylinderRadius, -theVertCylinderRadius, 0);
1329 box_e->GetLastFunction()->SetDescription("");
1331 aFunction = theShape->GetLastFunction();
1332 theDesc = aFunction->GetDescription();
1333 Handle(TColStd_HSequenceOfTransient) extremVertices =
1334 myShapesOperations->GetShapesOnBox(box_e, theShape, TopAbs_VERTEX, GEOMAlgo_ST_ONIN);
1335 // Recover previous description to get rid of Propagate dump
1336 aFunction->SetDescription(theDesc);
1338 if (extremVertices.IsNull() || extremVertices->Length() == 0) {
1340 SetErrorCode("Vertices on chamfer not found");
1342 SetErrorCode("Vertices on fillet not found");
1346 theShapes.push_back(theShape);
1347 theShapes.push_back(box_e);
1348 if (extremVertices->Length() != 6) {
1349 // for (int i=1; i<=extremVertices->Length(); i++){
1350 // theShapes.push_back(Handle(GEOM_Object)::DownCast(extremVertices->Value(i)));
1352 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1353 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1354 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1355 SetErrorCode("Bad number of vertices on chamfer found");
1359 for (int i=1; i<=extremVertices->Length(); i++){
1360 Handle(GEOM_Object) aV = Handle(GEOM_Object)::DownCast(extremVertices->Value(i));
1361 aV->GetLastFunction()->SetDescription("");
1362 gp_Pnt aP = BRep_Tool::Pnt(TopoDS::Vertex(aV->GetValue()));
1364 if (Abs(aP.X()) <= Precision::Confusion()) {
1365 if (Abs(aP.Y()) - theR2 > Precision::Confusion()) {
1367 if (aP.Z()-ZX > Precision::Confusion()) {
1374 if (Abs(aP.X()) - theR2 > Precision::Confusion()) {
1376 if (aP.Z() - ZY > Precision::Confusion()) {
1387 if (LX.at(0) == PZX)
1390 if (LY.at(0) == PZY)
1393 P1 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP1));
1394 P2 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP2));
1395 P3 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP3));
1396 P4 = Handle(GEOM_Object)::DownCast(extremVertices->Value(idP4));
1398 Handle(GEOM_Object) Cote_1 = myBasicOperations->MakeLineTwoPnt(P1, vi1);
1399 if (Cote_1.IsNull()) {
1400 SetErrorCode("Impossible to build edge in thickness");
1403 Cote_1->GetLastFunction()->SetDescription("");
1405 Handle(GEOM_Object) Cote_2 = myBasicOperations->MakeLineTwoPnt(vi2, P3);
1406 if (Cote_2.IsNull()) {
1407 SetErrorCode("Impossible to build edge in thickness");
1410 Cote_2->GetLastFunction()->SetDescription("");
1412 // edge_chan_princ = arete du chanfrein (ou raccord) sur le tuyau principal
1413 // edge_chan_inc = arete du chanfrein (ou raccord) sur le tuyau incident
1414 // std::cerr << "Getting chamfer edge on main pipe" << std::endl;
1415 Handle(GEOM_Object) edge_chan_princ = myBlocksOperations->GetEdge(theShape, P1, P3);
1416 if (edge_chan_princ.IsNull()) {
1417 SetErrorCode("Impossible to find edge on main pipe");
1420 edge_chan_princ->GetLastFunction()->SetDescription("");
1422 Handle(GEOM_Object) edge_chan_inc = myBlocksOperations->GetEdge(theShape, P2, P4);
1423 if (edge_chan_inc.IsNull()) {
1424 SetErrorCode("Impossible to find edge on incident pipe");
1427 edge_chan_inc->GetLastFunction()->SetDescription("");
1429 std::list<Handle(GEOM_Object)> edgeList1;
1430 edgeList1.push_back(edge_chan_princ);
1431 edgeList1.push_back(Cote_1);
1432 edgeList1.push_back(arete_intersect_int);
1433 edgeList1.push_back(Cote_2);
1435 // std::cerr << "Creating wire 1" << std::endl;
1436 wire_t = myShapesOperations->MakeWire(edgeList1, 1e-7);
1437 if (wire_t.IsNull()) {
1438 SetErrorCode("Impossible to build wire");
1441 wire_t->GetLastFunction()->SetDescription("");
1443 // std::cerr << "Creating face 1" << std::endl;
1444 face_t = myShapesOperations->MakeFace(wire_t, false);
1445 if (face_t.IsNull()) {
1446 SetErrorCode("Impossible to build face");
1449 face_t->GetLastFunction()->SetDescription("");
1450 theShapes.push_back(face_t);
1452 gp_Pnt aP2 = BRep_Tool::Pnt(TopoDS::Vertex(P2->GetValue()));
1453 gp_Pnt aP5 = BRep_Tool::Pnt(TopoDS::Vertex(vi1->GetValue()));
1454 double deltaZ = aP2.Z() - aP5.Z();
1455 // std::cerr << "Creating new point from vi1 with deltaZ = " << deltaZ << std::endl;
1456 Handle(GEOM_Object) P5bis = myTransformOperations->TranslateDXDYDZCopy(vi1, 0, 0, deltaZ);
1457 if (P5bis.IsNull()) {
1458 SetErrorCode("Impossible to translate vertex");
1461 P5bis->GetLastFunction()->SetDescription("");
1463 gp_Pnt aP4 = BRep_Tool::Pnt(TopoDS::Vertex(P4->GetValue()));
1464 gp_Pnt aP6 = BRep_Tool::Pnt(TopoDS::Vertex(vi2->GetValue()));
1465 deltaZ = aP4.Z() - aP6.Z();
1466 // std::cerr << "Creating new point from vi2 with deltaZ = " << deltaZ << std::endl;
1467 Handle(GEOM_Object) P6bis = myTransformOperations->TranslateDXDYDZCopy(vi2, 0, 0, deltaZ);
1468 if (P6bis.IsNull()) {
1469 SetErrorCode("Impossible to translate vertex");
1472 P6bis->GetLastFunction()->SetDescription("");
1474 // std::cerr << "Creating new line 1 from 2 previous points" << std::endl;
1475 Handle(GEOM_Object) Cote_3 = myBasicOperations->MakeLineTwoPnt(P5bis, P2);
1476 if (Cote_3.IsNull()) {
1477 SetErrorCode("Impossible to build edge in thickness");
1480 Cote_3->GetLastFunction()->SetDescription("");
1482 // std::cerr << "Creating new line 2 from 2 previous points" << std::endl;
1483 Handle(GEOM_Object) Cote_4 = myBasicOperations->MakeLineTwoPnt(P6bis, P4);
1484 if (Cote_4.IsNull()) {
1485 SetErrorCode("Impossible to build edge in thickness");
1488 Cote_4->GetLastFunction()->SetDescription("");
1490 // std::cerr << "Creating new line 3 from 2 previous points" << std::endl;
1491 Handle(GEOM_Object) Cote_5 = myBasicOperations->MakeLineTwoPnt(P5bis, P6bis);
1492 if (Cote_4.IsNull()) {
1493 SetErrorCode("Impossible to build edge in thickness");
1496 Cote_5->GetLastFunction()->SetDescription("");
1498 //std::list<Handle(GEOM_Object)> edgeList2;
1499 //edgeList2.push_back(edge_chan_inc);
1500 //edgeList2.push_back(Cote_3);
1501 //edgeList2.push_back(Cote_5);
1502 //edgeList2.push_back(Cote_4);
1503 // std::cerr << "Creating wire 2" << std::endl;
1504 //wire_t2 = myShapesOperations->MakeWire(edgeList2, 1e-7);
1505 //if (wire_t2.IsNull()) {
1506 // SetErrorCode("Impossible to build wire");
1509 //wire_t2->GetLastFunction()->SetDescription("");
1510 // std::cerr << "Creating face 2" << std::endl;
1511 //face_t2 = myShapesOperations->MakeFace(wire_t2, false);
1513 // Mantis issue 0021682
1514 face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - (theR2 + theW2));
1515 //face_t2 = my3DPrimOperations->MakePrismVecH(edge_chan_inc, Cote_4, - 2.0*theR2);
1516 if (face_t2.IsNull()) {
1517 SetErrorCode("Impossible to build face");
1520 face_t2->GetLastFunction()->SetDescription("");
1521 theShapes.push_back(face_t2);
1525 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1526 Handle(GEOM_Object) aVZ = myBasicOperations->MakeVectorDXDYDZ(0, 0, 1);
1527 Handle(GEOM_Object) aVXZ = myBasicOperations->MakeVectorDXDYDZ(aR1Ext, 0, 0.5*(theL1+theVertCylinderRadius));
1528 Handle(GEOM_Object) aPlnOZ = myBasicOperations->MakePlanePntVec(aP0, aVZ, aSize);
1529 Handle(GEOM_Object) aPlnOXZ = myBasicOperations->MakePlanePntVec(aP0, aVXZ, aSize);
1530 aP0->GetLastFunction()->SetDescription("");
1531 aVZ->GetLastFunction()->SetDescription("");
1532 aVXZ->GetLastFunction()->SetDescription("");
1533 aPlnOZ->GetLastFunction()->SetDescription("");
1534 aPlnOXZ->GetLastFunction()->SetDescription("");
1535 theShapes.push_back(aPlnOZ);
1536 theShapes.push_back(aPlnOXZ);
1539 Handle(TColStd_HSequenceOfTransient) partitionShapes = new TColStd_HSequenceOfTransient;
1540 Handle(TColStd_HSequenceOfTransient) theTools = new TColStd_HSequenceOfTransient;
1541 Handle(TColStd_HSequenceOfTransient) theKeepInside = new TColStd_HSequenceOfTransient;
1542 Handle(TColStd_HSequenceOfTransient) theRemoveInside = new TColStd_HSequenceOfTransient;
1543 Handle(TColStd_HArray1OfInteger) theMaterials;
1545 partitionShapes->Append(theShape);
1546 theTools->Append(aPlnOZ);
1547 if (Abs(aR1Ext - aR2Ext) > Precision::Confusion())
1548 theTools->Append(aPlnOXZ);
1549 theTools->Append(face_t);
1551 theTools->Append(face_t2);
1553 Te3 = myBooleanOperations->MakePartition
1554 (partitionShapes, theTools, theKeepInside, theRemoveInside,
1555 TopAbs_SOLID, false, theMaterials, 0, false);
1557 SetErrorCode("Impossible to build partition of TShape");
1560 Te3->GetLastFunction()->SetDescription("");
1562 // Last verification: result should be a block
1563 std::list<GEOMImpl_IBlocksOperations::BCError> errList;
1564 if (!myBlocksOperations->CheckCompoundOfBlocks(Te3,errList)) {
1565 SetErrorCode("TShape is not a compound of block");
1569 // // BEGIN Compound of created shapes - Only for debug purpose
1570 // theShapes.clear();
1571 // theShapes.push_back(theShape);
1572 // theShapes.push_back(aPlnOZ);
1573 // if (Abs(aR1Ext - aR2Ext) > Precision::Confusion() )
1574 // theShapes.push_back(aPlnOXZ);
1575 // theShapes.push_back(face_t);
1577 // theShapes.push_back(face_t2);
1579 // Handle(GEOM_Object) aCompound = myShapesOperations->MakeCompound(theShapes);
1580 // TopoDS_Shape aCompoundShape = aCompound->GetValue();
1581 // theShape->GetLastFunction()->SetValue(aCompoundShape);
1582 // // END Compound of created shapes - Only for debug purpose
1584 TopoDS_Shape aShape = Te3->GetValue();
1585 theShape->GetLastFunction()->SetValue(aShape);
1587 catch (Standard_Failure) {
1588 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1589 SetErrorCode(aFail->GetMessageString());
1597 // Mirror and glue faces
1598 bool GEOMImpl_IAdvancedOperations::MakePipeTShapeMirrorAndGlue(Handle(GEOM_Object) theShape,
1599 double theR1, double theW1, double theL1,
1600 double theR2, double theW2, double theL2)
1605 double aSize = 2*(theL1 + theL2);
1606 double aR1Ext = theR1 + theW1;
1609 Handle(GEOM_Object) aP0 = myBasicOperations->MakePointXYZ(0, 0, 0);
1610 aP0->GetLastFunction()->SetDescription("");
1611 Handle(GEOM_Object) aVX = myBasicOperations->MakeVectorDXDYDZ(1, 0, 0);
1612 Handle(GEOM_Object) aVY = myBasicOperations->MakeVectorDXDYDZ(0, 1, 0);
1613 aVX->GetLastFunction()->SetDescription("");
1614 aVY->GetLastFunction()->SetDescription("");
1615 Handle(GEOM_Object) aPlane_OX = myBasicOperations->MakePlanePntVec(aP0, aVX, 2*(aR1Ext + theL2));
1616 Handle(GEOM_Object) aPlane_OY = myBasicOperations->MakePlanePntVec(aP0, aVY, aSize);
1617 aPlane_OX->GetLastFunction()->SetDescription("");
1618 aPlane_OY->GetLastFunction()->SetDescription("");
1620 Handle(GEOM_Object) Te4 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OX);
1622 SetErrorCode("Impossible to build mirror of quarter TShape");
1626 Handle(GEOM_Object) Te5 = myTransformOperations->MirrorPlaneCopy(theShape, aPlane_OY);
1628 SetErrorCode("Impossible to build mirror of half TShape");
1632 Handle(GEOM_Object) Te6 = myTransformOperations->MirrorPlaneCopy(Te4, aPlane_OY);
1634 SetErrorCode("Impossible to build mirror of half TShape");
1638 std::list<Handle(GEOM_Object)> aShapesList;
1639 aShapesList.push_back(theShape);
1640 aShapesList.push_back(Te4);
1641 aShapesList.push_back(Te5);
1642 aShapesList.push_back(Te6);
1643 Handle(GEOM_Object) Te7 = myShapesOperations->MakeCompound(aShapesList);
1645 SetErrorCode("Impossible to build compound");
1649 // Copy source shape
1650 TopoDS_Shape aShapeCopy;
1651 TColStd_IndexedDataMapOfTransientTransient aMapTShapes;
1652 TNaming_CopyShape::CopyTool(Te7->GetValue(), aMapTShapes, aShapeCopy);
1654 Handle(GEOM_Object) Te8 = myShapesOperations->MakeGlueFaces(Te7, 1e-7, true);
1656 SetErrorCode("Impossible to glue faces of TShape");
1660 TopoDS_Shape aShape = Te8->GetValue();
1661 BRepCheck_Analyzer anAna (aShape, Standard_True);
1663 if (!anAna.IsValid()) {
1664 // Try to do gluing with the tolerance equal to maximal
1665 // tolerance of vertices of the source shape.
1666 Standard_Real aTolMax = -RealLast();
1668 for (TopExp_Explorer ExV (aShapeCopy, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1669 TopoDS_Vertex aVertex = TopoDS::Vertex(ExV.Current());
1670 Standard_Real aTol = BRep_Tool::Tolerance(aVertex);
1672 if (aTol > aTolMax) {
1678 Te7->GetLastFunction()->SetValue(aShapeCopy);
1679 Te8 = myShapesOperations->MakeGlueFaces(Te7, aTolMax, true);
1682 SetErrorCode("Impossible to glue faces of TShape");
1686 aShape = Te8->GetValue();
1690 theShape->GetLastFunction()->SetValue(aShape);
1692 Te4->GetLastFunction()->SetDescription("");
1693 Te5->GetLastFunction()->SetDescription("");
1694 Te6->GetLastFunction()->SetDescription("");
1695 Te7->GetLastFunction()->SetDescription("");
1696 Te8->GetLastFunction()->SetDescription("");
1702 //=======================================================================
1703 //function : MakePipeTShapeThicknessReduction
1704 //purpose : Static method. Add thiskness reduction elements at the three
1705 // open ends of the T-Shape.
1706 //=======================================================================
1707 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakePipeTShapeThicknessReduction
1708 (TopoDS_Shape theShape,
1709 double r1, double w1, double l1,
1710 double r2, double w2, double l2,
1711 double rL, double wL, double ltransL, double lthinL,
1712 double rR, double wR, double ltransR, double lthinR,
1713 double rI, double wI, double ltransI, double lthinI,
1714 bool fuseReductions)
1716 // Add thickness reduction elements
1717 // at the three extremities: Left, Right and Incident
1719 // ---------------------.
1721 // ---------------------. \
1722 // ^ \ '-----------------.
1724 // | '-----------------'
1726 // --.--.--.--.--.--.--.--.--.--.--.--.--.--.--
1729 TopoDS_Shape aResult = theShape;
1730 double aTol = Precision::Confusion();
1732 gp_Vec aVX = gp::DX(), aVZ = gp::DZ();
1734 // Left reduction (rL, wL, ltransL, lthinL)
1735 if (rL > aTol && wL > aTol && ltransL > aTol) {
1736 gp_Pnt aPLeft (-l1, 0, 0);
1737 gp_Ax2 anAxesLeft (aPLeft, -aVX, aVZ);
1738 TopoDS_Shape aReductionLeft = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1739 (anAxesLeft, r1, w1, rL, wL, ltransL, lthinL, fuseReductions);
1741 if (fuseReductions) {
1742 BRepAlgoAPI_Fuse fuseL (aResult, aReductionLeft);
1743 if (!fuseL.IsDone())
1744 StdFail_NotDone::Raise("Cannot fuse Te with left reduction");
1745 aResult = fuseL.Shape();
1752 B.Add(C, aReductionLeft);
1758 if (rR > aTol && wR > aTol && ltransR > aTol) {
1759 gp_Pnt aPRight (l1, 0, 0);
1760 gp_Ax2 anAxesRight (aPRight, aVX, aVZ);
1761 TopoDS_Shape aReductionRight = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1762 (anAxesRight, r1, w1, rR, wR, ltransR, lthinR, fuseReductions);
1764 if (fuseReductions) {
1765 BRepAlgoAPI_Fuse fuseR (aResult, aReductionRight);
1766 if (!fuseR.IsDone())
1767 StdFail_NotDone::Raise("Cannot fuse Te with right reduction");
1768 aResult = fuseR.Shape();
1775 B.Add(C, aReductionRight);
1780 // Incident reduction
1781 if (rI > aTol && wI > aTol && ltransI > aTol) {
1782 gp_Pnt aPInci (0, 0, l2);
1783 gp_Ax2 anAxesInci (aPInci, aVZ, aVX);
1784 TopoDS_Shape aReductionInci = GEOMImpl_IAdvancedOperations::MakeThicknessReduction
1785 (anAxesInci, r2, w2, rI, wI, ltransI, lthinI, fuseReductions);
1787 if (fuseReductions) {
1788 BRepAlgoAPI_Fuse fuseInci (aResult, aReductionInci);
1789 if (!fuseInci.IsDone())
1790 StdFail_NotDone::Raise("Cannot fuse Te with incident reduction");
1791 aResult = fuseInci.Shape();
1798 B.Add(C, aReductionInci);
1803 // Get rid of extra compounds
1804 TopTools_ListOfShape listShapeRes;
1805 GEOMUtils::AddSimpleShapes(aResult, listShapeRes);
1806 aResult = listShapeRes.First(); // useful for the case "fuseReductions == true"
1808 if (!fuseReductions && listShapeRes.Extent() > 1) {
1809 // Simplify T-Shape compound (get rid of sub-compounds) and glue duplicated faces
1814 TopTools_ListIteratorOfListOfShape itSub (listShapeRes);
1815 for (; itSub.More(); itSub.Next())
1816 B.Add(C, itSub.Value());
1819 aResult = GEOMImpl_GlueDriver::GlueFaces(C, Precision::Confusion(), Standard_True);
1825 //=======================================================================
1826 //function : MakeThicknessReduction
1827 //purpose : Static method. Create one thickness reduction element.
1828 //=======================================================================
1829 TopoDS_Shape GEOMImpl_IAdvancedOperations::MakeThicknessReduction (gp_Ax2 theAxes,
1830 const double R, const double W,
1831 const double Rthin, const double Wthin,
1832 const double Ltrans, const double Lthin,
1835 double aTol = Precision::Confusion();
1836 if (Rthin < aTol || Wthin < aTol || Ltrans < aTol) {
1837 StdFail_NotDone::Raise("Cannot build thickness reduction: too small values");
1839 bool isThinPart = (Lthin > aTol);
1844 // ^ \ '-----------------.
1846 // | '-----------------'
1848 // --.--.--.--.--.--.--.--.--.--.--.--.--> theAxes.Direction()
1851 double RExt = R + W;
1852 double RthinExt = Rthin + Wthin;
1854 gp_Dir aNormal = theAxes.Direction();
1855 gp_Dir anXDir = theAxes.XDirection();
1856 gp_Pnt aPntCyl (theAxes.Location().XYZ() + aNormal.XYZ()*Ltrans);
1857 gp_Ax2 anAxesCyl (aPntCyl, aNormal, anXDir);
1859 // Build the transition part
1860 BRepPrimAPI_MakeCone ConeExt (theAxes, RExt, RthinExt, Ltrans);
1861 BRepPrimAPI_MakeCone ConeInt (theAxes, R, Rthin, Ltrans);
1864 if (!ConeExt.IsDone() || !ConeInt.IsDone())
1865 StdFail_NotDone::Raise("Cannot build cones of thickness reduction");
1866 BRepAlgoAPI_Cut cut1 (ConeExt.Shape(), ConeInt.Shape());
1868 StdFail_NotDone::Raise("Coudn't build transition part of thickness reduction");
1869 TopoDS_Shape aReduction = cut1.Shape();
1871 // Build the thin part, if required
1872 TopoDS_Shape aThinPart;
1874 BRepPrimAPI_MakeCylinder CExt (anAxesCyl, RthinExt, Lthin);
1875 BRepPrimAPI_MakeCylinder CInt (anAxesCyl, Rthin, Lthin);
1878 if (!CExt.IsDone() || !CInt.IsDone())
1879 StdFail_NotDone::Raise("Cannot build cylinders of thickness reduction");
1880 BRepAlgoAPI_Cut cut2 (CExt.Shape(), CInt.Shape());
1882 StdFail_NotDone::Raise("Coudn't build thin part of thickness reduction");
1883 aThinPart = cut2.Shape();
1889 BRepAlgoAPI_Fuse fuse1 (aReduction, aThinPart);
1890 if (!fuse1.IsDone())
1891 StdFail_NotDone::Raise("Cannot fuse parts of thickness reduction");
1892 aReduction = fuse1.Shape();
1896 // Partition the reduction on blocks
1897 gp_Ax3 anAxesPln1 (aPntCyl, theAxes.XDirection(), aNormal);
1898 gp_Ax3 anAxesPln2 (aPntCyl, theAxes.YDirection(), aNormal);
1899 gp_Pln aPln1 (anAxesPln1);
1900 gp_Pln aPln2 (anAxesPln2);
1901 double aSize = Ltrans + Lthin + R + Rthin + Wthin; // to guarantee enough size in all directions
1902 TopoDS_Shape aTool1 = BRepBuilderAPI_MakeFace(aPln1, -aSize, +aSize, -aSize, +aSize).Shape();
1903 TopoDS_Shape aTool2 = BRepBuilderAPI_MakeFace(aPln2, -aSize, +aSize, -aSize, +aSize).Shape();
1905 GEOMAlgo_Splitter PS;
1906 PS.AddShape(aReduction);
1908 PS.AddShape(aThinPart);
1911 PS.SetLimit(TopAbs_SOLID);
1914 aReduction = PS.Shape();
1920 //=============================================================================
1923 * \brief Create a T-shape object with specified caracteristics for the main and
1924 * the incident pipes (radius, width, half-length).
1925 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
1926 * \param theR1 Internal radius of main pipe
1927 * \param theW1 Width of main pipe
1928 * \param theL1 Half-length of main pipe
1929 * \param theR2 Internal radius of incident pipe (R2 < R1)
1930 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
1931 * \param theL2 Half-length of incident pipe
1932 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
1933 * \return List of GEOM_Objects, containing the created shape and propagation groups.
1935 //=============================================================================
1936 Handle(TColStd_HSequenceOfTransient)
1937 GEOMImpl_IAdvancedOperations::MakePipeTShape(double theR1, double theW1, double theL1,
1938 double theR2, double theW2, double theL2,
1939 double theRL, double theWL, double theLtransL, double theLthinL,
1940 double theRR, double theWR, double theLtransR, double theLthinR,
1941 double theRI, double theWI, double theLtransI, double theLthinI,
1944 MESSAGE("GEOMImpl_IAdvancedOperations::MakePipeTShape");
1947 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
1949 //Add a new shape function with parameters
1950 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
1951 if (aFunction.IsNull()) return NULL;
1953 //Check if the function is set correctly
1954 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
1956 GEOMImpl_IPipeTShape aData (aFunction);
1964 aData.SetHexMesh(theHexMesh);
1966 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
1967 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
1968 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
1970 //Compute the resulting value
1972 #if OCC_VERSION_LARGE > 0x06010000
1975 if (!GetSolver()->ComputeFunction(aFunction)) {
1976 SetErrorCode("TShape driver failed");
1981 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1983 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
1987 if (isTRL || isTRR || isTRI) {
1988 // Add thickness reduction elements
1989 // at the three extremities: Left, Right and Incident
1990 TopoDS_Shape aResShape =
1991 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
1992 theRL, theWL, theLtransL, theLthinL,
1993 theRR, theWR, theLtransR, theLthinR,
1994 theRI, theWI, theLtransI, theLthinI,
1996 aFunction->SetValue(aResShape);
1999 catch (Standard_Failure) {
2000 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2001 SetErrorCode(aFail->GetMessageString());
2005 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2006 aSeq->Append(aShape);
2011 if (!MakeGroups(aShape, TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2012 0., 0., 0., aSeq, gp_Trsf()))
2016 // Get internal group.
2017 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2018 theRR, theLtransR, theRI, theLtransI,
2023 catch (Standard_Failure) {
2024 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2025 SetErrorCode(aFail->GetMessageString());
2029 //Make a Python command
2030 TCollection_AsciiString anEntry, aListRes("[");
2031 // Iterate over the sequence aSeq
2032 Standard_Integer aNbGroups = aSeq->Length();
2033 Standard_Integer i = 1;
2034 for (; i <= aNbGroups; i++) {
2035 Handle(Standard_Transient) anItem = aSeq->Value(i);
2036 if (anItem.IsNull()) continue;
2037 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2038 if (aGroup.IsNull()) continue;
2039 //Make a Python command
2040 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2041 aListRes += anEntry + ", ";
2043 aListRes.Trunc(aListRes.Length() - 2);
2045 GEOM::TPythonDump pd (aFunction);
2047 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2048 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2049 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2052 // thickness reduction
2054 pd << ", theRL=" << theRL << ", theWL=" << theWL
2055 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2057 pd << ", theRR=" << theRR << ", theWR=" << theWR
2058 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2060 pd << ", theRI=" << theRI << ", theWI=" << theWI
2061 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2070 //=============================================================================
2072 * MakePipeTShapeWithPosition
2073 * Create a T-shape object with specified caracteristics for the main and
2074 * the incident pipes (radius, width, half-length).
2075 * The extremities of the main pipe are located on junctions points P1 and P2.
2076 * The extremity of the incident pipe is located on junction point P3.
2077 * \param theR1 Internal radius of main pipe
2078 * \param theW1 Width of main pipe
2079 * \param theL1 Half-length of main pipe
2080 * \param theR2 Internal radius of incident pipe (R2 < R1)
2081 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2082 * \param theL2 Half-length of incident pipe
2083 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2084 * \param theP1 1st junction point of main pipe
2085 * \param theP2 2nd junction point of main pipe
2086 * \param theP3 Junction point of incident pipe
2087 * \return List of GEOM_Objects, containing the created shape and propagation groups..
2089 //=============================================================================
2090 Handle(TColStd_HSequenceOfTransient)
2091 GEOMImpl_IAdvancedOperations::MakePipeTShapeWithPosition
2092 (double theR1, double theW1, double theL1,
2093 double theR2, double theW2, double theL2,
2094 double theRL, double theWL, double theLtransL, double theLthinL,
2095 double theRR, double theWR, double theLtransR, double theLthinR,
2096 double theRI, double theWI, double theLtransI, double theLthinI,
2098 Handle(GEOM_Object) theP1,
2099 Handle(GEOM_Object) theP2,
2100 Handle(GEOM_Object) theP3)
2104 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2108 //Add a new shape function with parameters
2109 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_BASIC);
2110 if (aFunction.IsNull()) return NULL;
2112 //Check if the function is set correctly
2113 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2115 // Check new position
2116 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2120 GEOMImpl_IPipeTShape aData(aFunction);
2128 aData.SetHexMesh(theHexMesh);
2130 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2131 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2132 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2134 //Compute the resulting value
2136 #if OCC_VERSION_LARGE > 0x06010000
2139 if (!GetSolver()->ComputeFunction(aFunction)) {
2140 SetErrorCode("TShape driver failed");
2145 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2147 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2151 if (isTRL || isTRR || isTRI) {
2152 // Add thickness reduction elements
2153 // at the three extremities: Left, Right and Incident
2154 TopoDS_Shape aResShape =
2155 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2156 theRL, theWL, theLtransL, theLthinL,
2157 theRR, theWR, theLtransR, theLthinR,
2158 theRI, theWI, theLtransI, theLthinI,
2160 aFunction->SetValue(aResShape);
2163 catch (Standard_Failure) {
2164 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2165 SetErrorCode(aFail->GetMessageString());
2169 TopoDS_Shape Te = aShape->GetValue();
2172 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2173 BRepBuilderAPI_Transform aTransformation(Te, aTrsf, Standard_False);
2174 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2175 aFunction->SetValue(aTrsf_Shape);
2177 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2178 aSeq->Append(aShape);
2183 if (!MakeGroups(aShape,TSHAPE_BASIC, theR1, theW1, theL1, theR2, theW2, theL2,
2184 0., 0., 0., aSeq, aTrsf)) {
2189 // Get internal group.
2190 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2191 theRR, theLtransR, theRI, theLtransI,
2196 catch (Standard_Failure) {
2197 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2198 SetErrorCode(aFail->GetMessageString());
2202 //Make a Python command
2203 TCollection_AsciiString anEntry, aListRes("[");
2204 // Iterate over the sequence aSeq
2205 Standard_Integer aNbGroups = aSeq->Length();
2206 Standard_Integer i = 1;
2207 for (; i <= aNbGroups; i++) {
2208 Handle(Standard_Transient) anItem = aSeq->Value(i);
2209 if (anItem.IsNull()) continue;
2210 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2211 if (aGroup.IsNull()) continue;
2212 //Make a Python command
2213 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2214 aListRes += anEntry + ", ";
2216 aListRes.Trunc(aListRes.Length() - 2);
2218 GEOM::TPythonDump pd (aFunction);
2220 pd << aListRes.ToCString() << "] = geompy.MakePipeTShape("
2221 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2222 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2223 << theHexMesh << ", " << theP1 << ", " << theP2 << ", " << theP3;
2225 // thickness reduction
2227 pd << ", theRL=" << theRL << ", theWL=" << theWL
2228 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2230 pd << ", theRR=" << theRR << ", theWR=" << theWR
2231 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2233 pd << ", theRI=" << theRI << ", theWI=" << theWI
2234 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2243 //=============================================================================
2245 * MakePipeTShapeChamfer
2246 * Create a T-shape object with specified caracteristics for the main and
2247 * the incident pipes (radius, width, half-length). A chamfer is created
2248 * on the junction of the pipes.
2249 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2250 * \param theR1 Internal radius of main pipe
2251 * \param theW1 Width of main pipe
2252 * \param theL1 Half-length of main pipe
2253 * \param theR2 Internal radius of incident pipe (R2 < R1)
2254 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2255 * \param theL2 Half-length of incident pipe
2256 * \param theH Height of chamfer.
2257 * \param theW Width of chamfer.
2258 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2259 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2261 //=============================================================================
2262 Handle(TColStd_HSequenceOfTransient)
2263 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamfer
2264 (double theR1, double theW1, double theL1,
2265 double theR2, double theW2, double theL2,
2266 double theRL, double theWL, double theLtransL, double theLthinL,
2267 double theRR, double theWR, double theLtransR, double theLthinR,
2268 double theRI, double theWI, double theLtransI, double theLthinI,
2269 double theH, double theW,
2274 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2275 //Add a new shape function with parameters
2276 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2277 if (aFunction.IsNull()) return NULL;
2279 //Check if the function is set correctly
2280 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2282 GEOMImpl_IPipeTShape aData(aFunction);
2292 aData.SetHexMesh(theHexMesh);
2294 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2295 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2296 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2298 //Compute the resulting value
2300 #if OCC_VERSION_LARGE > 0x06010000
2303 if (!GetSolver()->ComputeFunction(aFunction)) {
2304 SetErrorCode("TShape driver failed");
2308 catch (Standard_Failure) {
2309 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2310 SetErrorCode(aFail->GetMessageString());
2315 TopoDS_Shape aShapeShape = aShape->GetValue();
2316 TopTools_IndexedMapOfShape anEdgesIndices;
2317 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2318 // Common edges on external cylinders
2319 Handle(GEOM_Object) box_e;
2321 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2324 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2326 box_e->GetLastFunction()->SetDescription("");
2327 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2328 box_e->GetLastFunction()->SetDescription("");
2330 Handle(TColStd_HSequenceOfInteger) edges_e =
2331 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2332 box_e->GetLastFunction()->SetDescription("");
2334 if (edges_e.IsNull() || edges_e->Length() == 0) {
2335 SetErrorCode("External edges not found");
2338 int nbEdgesInChamfer = 0;
2339 std::list<int> theEdges;
2340 for (int i=1; i<=edges_e->Length();i++) {
2341 int edgeID = edges_e->Value(i);
2342 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2343 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2347 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2348 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2349 nbEdgesInChamfer ++;
2350 theEdges.push_back(edgeID);
2354 if (theHexMesh && nbEdgesInChamfer == 1)
2357 Handle(GEOM_Object) aChamfer;
2359 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2361 catch (Standard_Failure) {
2362 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2363 SetErrorCode(aFail->GetMessageString());
2366 if (aChamfer.IsNull()) {
2367 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2370 aChamfer->GetLastFunction()->SetDescription("");
2372 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2373 aFunction->SetValue(aChamferShape);
2377 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2379 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2383 // Add thickness reduction elements
2384 // at the three extremities: Left, Right and Incident
2386 #if OCC_VERSION_LARGE > 0x06010000
2389 if (isTRL || isTRR || isTRI) {
2390 TopoDS_Shape aResShape =
2391 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2392 theRL, theWL, theLtransL, theLthinL,
2393 theRR, theWR, theLtransR, theLthinR,
2394 theRI, theWI, theLtransI, theLthinI,
2396 aFunction->SetValue(aResShape);
2399 catch (Standard_Failure) {
2400 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2401 SetErrorCode(aFail->GetMessageString());
2405 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2406 aSeq->Append(aShape);
2411 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2412 theH, theW, 0., aSeq, gp_Trsf()))
2416 // Get internal group.
2417 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2418 theRR, theLtransR, theRI, theLtransI,
2423 catch (Standard_Failure) {
2424 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2425 SetErrorCode(aFail->GetMessageString());
2429 //Make a Python command
2430 TCollection_AsciiString anEntry, aListRes("[");
2431 // Iterate over the sequence aSeq
2432 Standard_Integer aNbGroups = aSeq->Length();
2433 Standard_Integer i = 1;
2434 for (; i <= aNbGroups; i++) {
2435 Handle(Standard_Transient) anItem = aSeq->Value(i);
2436 if (anItem.IsNull()) continue;
2437 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2438 if (aGroup.IsNull()) continue;
2439 //Make a Python command
2440 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2441 aListRes += anEntry + ", ";
2443 aListRes.Trunc(aListRes.Length() - 2);
2445 GEOM::TPythonDump pd (aFunction);
2447 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2448 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2449 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2450 << theH << ", " << theW << ", " << theHexMesh;
2452 // thickness reduction
2454 pd << ", theRL=" << theRL << ", theWL=" << theWL
2455 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2457 pd << ", theRR=" << theRR << ", theWR=" << theWR
2458 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2460 pd << ", theRI=" << theRI << ", theWI=" << theWI
2461 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2470 //=============================================================================
2472 * MakePipeTShapeChamferWithPosition
2473 * Create a T-shape object with specified caracteristics for the main and
2474 * the incident pipes (radius, width, half-length). A chamfer is created
2475 * on the junction of the pipes.
2476 * The extremities of the main pipe are located on junctions points P1 and P2.
2477 * The extremity of the incident pipe is located on junction point P3.
2478 * \param theR1 Internal radius of main pipe
2479 * \param theW1 Width of main pipe
2480 * \param theL1 Half-length of main pipe
2481 * \param theR2 Internal radius of incident pipe (R2 < R1)
2482 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2483 * \param theL2 Half-length of incident pipe
2484 * \param theH Height of chamfer.
2485 * \param theW Width of chamfer.
2486 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2487 * \param theP1 1st junction point of main pipe
2488 * \param theP2 2nd junction point of main pipe
2489 * \param theP3 Junction point of incident pipe
2490 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2492 //=============================================================================
2493 Handle(TColStd_HSequenceOfTransient)
2494 GEOMImpl_IAdvancedOperations::MakePipeTShapeChamferWithPosition
2495 (double theR1, double theW1, double theL1,
2496 double theR2, double theW2, double theL2,
2497 double theRL, double theWL, double theLtransL, double theLthinL,
2498 double theRR, double theWR, double theLtransR, double theLthinR,
2499 double theRI, double theWI, double theLtransI, double theLthinI,
2500 double theH, double theW,
2502 Handle(GEOM_Object) theP1,
2503 Handle(GEOM_Object) theP2,
2504 Handle(GEOM_Object) theP3)
2508 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2509 //Add a new shape function with parameters
2510 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_CHAMFER);
2511 if (aFunction.IsNull()) return NULL;
2513 //Check if the function is set correctly
2514 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2516 // Check new position
2517 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
2521 GEOMImpl_IPipeTShape aData(aFunction);
2531 aData.SetHexMesh(theHexMesh);
2533 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2534 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2535 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2537 //Compute the resulting value
2539 #if OCC_VERSION_LARGE > 0x06010000
2542 if (!GetSolver()->ComputeFunction(aFunction)) {
2543 SetErrorCode("TShape driver failed");
2547 catch (Standard_Failure) {
2548 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2549 SetErrorCode(aFail->GetMessageString());
2554 TopoDS_Shape aShapeShape = aShape->GetValue();
2555 TopTools_IndexedMapOfShape anEdgesIndices;
2556 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2557 // Common edges on external cylinders
2558 Handle(GEOM_Object) box_e;
2560 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2563 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2565 box_e->GetLastFunction()->SetDescription("");
2566 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2567 box_e->GetLastFunction()->SetDescription("");
2569 Handle(TColStd_HSequenceOfInteger) edges_e =
2570 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2571 box_e->GetLastFunction()->SetDescription("");
2573 if (edges_e.IsNull() || edges_e->Length() == 0) {
2574 SetErrorCode("External edges not found");
2577 int nbEdgesInChamfer = 0;
2578 std::list<int> theEdges;
2579 for (int i=1; i<=edges_e->Length();i++) {
2580 int edgeID = edges_e->Value(i);
2581 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2582 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2584 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2585 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2586 nbEdgesInChamfer ++;
2587 theEdges.push_back(edgeID);
2591 if (theHexMesh && nbEdgesInChamfer == 1)
2594 Handle(GEOM_Object) aChamfer;
2596 aChamfer = myLocalOperations->MakeChamferEdges(aShape, theW, theH, theEdges);
2598 catch (Standard_Failure) {
2599 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2600 SetErrorCode(aFail->GetMessageString());
2603 if (aChamfer.IsNull()) {
2604 SetErrorCode("Chamfer can not be computed on the given shape with the given parameters");
2607 aChamfer->GetLastFunction()->SetDescription("");
2609 TopoDS_Shape aChamferShape = aChamfer->GetValue();
2610 aFunction->SetValue(aChamferShape);
2614 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, theH, theW, 0, false))
2616 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2620 // Add thickness reduction elements
2621 // at the three extremities: Left, Right and Incident
2623 #if OCC_VERSION_LARGE > 0x06010000
2626 if (isTRL || isTRR || isTRI) {
2627 TopoDS_Shape aResShape =
2628 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2629 theRL, theWL, theLtransL, theLthinL,
2630 theRR, theWR, theLtransR, theLthinR,
2631 theRI, theWI, theLtransI, theLthinI,
2633 aFunction->SetValue(aResShape);
2636 catch (Standard_Failure) {
2637 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2638 SetErrorCode(aFail->GetMessageString());
2643 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
2644 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
2645 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
2646 aFunction->SetValue(aTrsf_Shape);
2648 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2649 aSeq->Append(aShape);
2654 if (!MakeGroups(aShape, TSHAPE_CHAMFER, theR1, theW1, theL1, theR2, theW2, theL2,
2655 theH, theW, 0., aSeq, aTrsf))
2659 // Get internal group.
2660 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2661 theRR, theLtransR, theRI, theLtransI,
2666 catch (Standard_Failure) {
2667 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2668 SetErrorCode(aFail->GetMessageString());
2672 //Make a Python command
2673 TCollection_AsciiString anEntry, aListRes("[");
2674 // Iterate over the sequence aSeq
2675 Standard_Integer aNbGroups = aSeq->Length();
2676 Standard_Integer i = 1;
2677 for (; i <= aNbGroups; i++) {
2678 Handle(Standard_Transient) anItem = aSeq->Value(i);
2679 if (anItem.IsNull()) continue;
2680 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2681 if (aGroup.IsNull()) continue;
2682 //Make a Python command
2683 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2684 aListRes += anEntry + ", ";
2686 aListRes.Trunc(aListRes.Length() - 2);
2688 GEOM::TPythonDump pd (aFunction);
2690 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeChamfer("
2691 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2692 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2693 << theH << ", " << theW << ", " << theHexMesh << ", "
2694 << theP1 << ", " << theP2 << ", " << theP3;
2696 // thickness reduction
2698 pd << ", theRL=" << theRL << ", theWL=" << theWL
2699 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2701 pd << ", theRR=" << theRR << ", theWR=" << theWR
2702 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2704 pd << ", theRI=" << theRI << ", theWI=" << theWI
2705 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2714 //=============================================================================
2716 * MakePipeTShapeFillet
2717 * Create a T-shape object with specified caracteristics for the main and
2718 * the incident pipes (radius, width, half-length). A fillet is created
2719 * on the junction of the pipes.
2720 * Center of the shape is (0,0,0). The main plane of the T-shape is XOY.
2721 * \param theR1 Internal radius of main pipe
2722 * \param theW1 Width of main pipe
2723 * \param theL1 Half-length of main pipe
2724 * \param theR2 Internal radius of incident pipe (R2 < R1)
2725 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2726 * \param theL2 Half-length of incident pipe
2727 * \param theRF Radius of curvature of fillet.
2728 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2729 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2731 //=============================================================================
2732 Handle(TColStd_HSequenceOfTransient)
2733 GEOMImpl_IAdvancedOperations::MakePipeTShapeFillet
2734 (double theR1, double theW1, double theL1,
2735 double theR2, double theW2, double theL2,
2736 double theRL, double theWL, double theLtransL, double theLthinL,
2737 double theRR, double theWR, double theLtransR, double theLthinR,
2738 double theRI, double theWI, double theLtransI, double theLthinI,
2739 double theRF, bool theHexMesh)
2743 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2744 //Add a new shape function with parameters
2745 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2746 if (aFunction.IsNull()) return NULL;
2748 //Check if the function is set correctly
2749 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2751 GEOMImpl_IPipeTShape aData(aFunction);
2760 aData.SetHexMesh(theHexMesh);
2762 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
2763 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
2764 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
2766 //Compute the resulting value
2768 #if OCC_VERSION_LARGE > 0x06010000
2771 if (!GetSolver()->ComputeFunction(aFunction)) {
2772 SetErrorCode("TShape driver failed");
2776 catch (Standard_Failure) {
2777 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2778 SetErrorCode(aFail->GetMessageString());
2783 TopoDS_Shape aShapeShape = aShape->GetValue();
2784 TopTools_IndexedMapOfShape anEdgesIndices;
2785 TopExp::MapShapes(aShapeShape, anEdgesIndices);
2786 // Common edges on external cylinders
2787 Handle(GEOM_Object) box_e;
2789 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
2792 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
2794 box_e->GetLastFunction()->SetDescription("");
2795 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
2796 box_e->GetLastFunction()->SetDescription("");
2798 Handle(TColStd_HSequenceOfInteger) edges_e =
2799 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
2800 box_e->GetLastFunction()->SetDescription("");
2802 if (edges_e.IsNull() || edges_e->Length() == 0) {
2803 SetErrorCode("External edges not found");
2806 int nbEdgesInFillet = 0;
2807 std::list<int> theEdges;
2808 for (int i=1; i<=edges_e->Length();i++) {
2809 int edgeID = edges_e->Value(i);
2810 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
2811 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
2813 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
2814 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
2816 theEdges.push_back(edgeID);
2820 if (theHexMesh && nbEdgesInFillet == 1)
2824 Handle(GEOM_Object) aFillet;
2826 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
2828 catch (Standard_Failure) {
2829 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2830 SetErrorCode(aFail->GetMessageString());
2833 if (aFillet.IsNull()) {
2834 //SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
2835 SetErrorCode(myLocalOperations->GetErrorCode());
2838 aFillet->GetLastFunction()->SetDescription("");
2840 TopoDS_Shape aFilletShape = aFillet->GetValue();
2841 aFunction->SetValue(aFilletShape);
2844 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (1)
2845 // the following block, when enabled, leads to partitioning problems
2847 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (1)
2848 // BEGIN: Limit tolerances (debug)
2849 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
2850 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
2851 aShape->GetLastFunction()->SetValue(aCorr1Shape);
2852 aCorr1->GetLastFunction()->SetDescription("");
2853 // END: Limit tolerances (debug)
2854 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (2)
2856 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (2)
2859 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
2861 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
2865 // Add thickness reduction elements
2866 // at the three extremities: Left, Right and Incident
2868 #if OCC_VERSION_LARGE > 0x06010000
2871 if (isTRL || isTRR || isTRI) {
2872 TopoDS_Shape aResShape =
2873 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
2874 theRL, theWL, theLtransL, theLthinL,
2875 theRR, theWR, theLtransR, theLthinR,
2876 theRI, theWI, theLtransI, theLthinI,
2878 aFunction->SetValue(aResShape);
2881 catch (Standard_Failure) {
2882 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2883 SetErrorCode(aFail->GetMessageString());
2887 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
2888 aSeq->Append(aShape);
2893 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
2894 0., 0., theRF, aSeq, gp_Trsf()))
2898 // Get internal group.
2899 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
2900 theRR, theLtransR, theRI, theLtransI,
2905 catch (Standard_Failure) {
2906 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
2907 SetErrorCode(aFail->GetMessageString());
2911 //Make a Python command
2912 TCollection_AsciiString anEntry, aListRes("[");
2913 // Iterate over the sequence aSeq
2914 Standard_Integer aNbGroups = aSeq->Length();
2915 Standard_Integer i = 1;
2916 for (; i <= aNbGroups; i++) {
2917 Handle(Standard_Transient) anItem = aSeq->Value(i);
2918 if (anItem.IsNull()) continue;
2919 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
2920 if (aGroup.IsNull()) continue;
2921 //Make a Python command
2922 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
2923 aListRes += anEntry + ", ";
2925 aListRes.Trunc(aListRes.Length() - 2);
2927 GEOM::TPythonDump pd (aFunction);
2929 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
2930 << theR1 << ", " << theW1 << ", " << theL1 << ", "
2931 << theR2 << ", " << theW2 << ", " << theL2 << ", "
2932 << theRF << ", " << theHexMesh;
2934 // thickness reduction
2936 pd << ", theRL=" << theRL << ", theWL=" << theWL
2937 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
2939 pd << ", theRR=" << theRR << ", theWR=" << theWR
2940 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
2942 pd << ", theRI=" << theRI << ", theWI=" << theWI
2943 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
2952 //=============================================================================
2954 * MakePipeTShapeFilletWithPosition
2955 * \brief Create a T-shape object with specified caracteristics for the main and
2956 * the incident pipes (radius, width, half-length). A fillet is created
2957 * on the junction of the pipes.
2958 * The extremities of the main pipe are located on junctions points P1 and P2.
2959 * The extremity of the incident pipe is located on junction point P3.
2960 * \param theR1 Internal radius of main pipe
2961 * \param theW1 Width of main pipe
2962 * \param theL1 Half-length of main pipe
2963 * \param theR2 Internal radius of incident pipe (R2 < R1)
2964 * \param theW2 Width of incident pipe (R2+W2 < R1+W1)
2965 * \param theL2 Half-length of incident pipe
2966 * \param theRF Radius of curvature of fillet
2967 * \param theHexMesh Boolean indicating if shape is prepared for hex mesh
2968 * \param theP1 1st junction point of main pipe
2969 * \param theP2 2nd junction point of main pipe
2970 * \param theP3 Junction point of incident pipe
2971 * \return List of GEOM_Objects, containing the created shape and propagation groups.
2973 //=============================================================================
2974 Handle(TColStd_HSequenceOfTransient)
2975 GEOMImpl_IAdvancedOperations::MakePipeTShapeFilletWithPosition
2976 (double theR1, double theW1, double theL1,
2977 double theR2, double theW2, double theL2,
2978 double theRL, double theWL, double theLtransL, double theLthinL,
2979 double theRR, double theWR, double theLtransR, double theLthinR,
2980 double theRI, double theWI, double theLtransI, double theLthinI,
2981 double theRF, bool theHexMesh,
2982 Handle(GEOM_Object) theP1,
2983 Handle(GEOM_Object) theP2,
2984 Handle(GEOM_Object) theP3)
2988 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_TSHAPE);
2989 //Add a new shape function with parameters
2990 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_PipeTShapeDriver::GetID(), TSHAPE_FILLET);
2991 if (aFunction.IsNull()) return NULL;
2993 //Check if the function is set correctly
2994 if (aFunction->GetDriverGUID() != GEOMImpl_PipeTShapeDriver::GetID()) return NULL;
2996 // Check new position
2997 if (!CheckCompatiblePosition(theL1, theL2, theP1, theP2, theP3, 0.01)) {
3001 GEOMImpl_IPipeTShape aData(aFunction);
3010 aData.SetHexMesh(theHexMesh);
3012 bool isTRL = (theRL + theWL + theLtransL + theLthinL) > Precision::Confusion();
3013 bool isTRR = (theRR + theWR + theLtransR + theLthinR) > Precision::Confusion();
3014 bool isTRI = (theRI + theWI + theLtransI + theLthinI) > Precision::Confusion();
3016 //Compute the resulting value
3018 #if OCC_VERSION_LARGE > 0x06010000
3021 if (!GetSolver()->ComputeFunction(aFunction)) {
3022 SetErrorCode("TShape driver failed");
3026 catch (Standard_Failure) {
3027 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3028 SetErrorCode(aFail->GetMessageString());
3033 TopoDS_Shape aShapeShape = aShape->GetValue();
3034 TopTools_IndexedMapOfShape anEdgesIndices;
3035 TopExp::MapShapes(aShapeShape, anEdgesIndices);
3036 // Common edges on external cylinders
3037 Handle(GEOM_Object) box_e;
3039 box_e = my3DPrimOperations->MakeBoxDXDYDZ(theR2+theW2, theR2+theW2, theR1+theW1);
3042 box_e = my3DPrimOperations->MakeBoxDXDYDZ(2*(theR2+theW2), 2*(theR2+theW2), theR1+theW1);
3044 box_e->GetLastFunction()->SetDescription("");
3045 box_e = myTransformOperations->TranslateDXDYDZ(box_e, -(theR2+theW2), -(theR2+theW2), 0);
3046 box_e->GetLastFunction()->SetDescription("");
3048 Handle(TColStd_HSequenceOfInteger) edges_e =
3049 myShapesOperations->GetShapesOnBoxIDs(box_e, aShape, TopAbs_EDGE, GEOMAlgo_ST_IN);
3050 box_e->GetLastFunction()->SetDescription("");
3052 if (edges_e.IsNull() || edges_e->Length() == 0) {
3053 SetErrorCode("External edges not found");
3056 int nbEdgesInFillet = 0;
3057 std::list<int> theEdges;
3058 for (int i=1; i<=edges_e->Length();i++) {
3059 int edgeID = edges_e->Value(i);
3060 TopoDS_Shape theEdge = anEdgesIndices.FindKey(edgeID);
3061 TopExp_Explorer Ex(theEdge,TopAbs_VERTEX);
3063 gp_Pnt aPt = BRep_Tool::Pnt(TopoDS::Vertex(Ex.Current()));
3064 if (Abs(aPt.Z() - (theR1+theW1)) <= Precision::Confusion()) {
3066 theEdges.push_back(edgeID);
3070 if (theHexMesh && nbEdgesInFillet == 1)
3074 Handle(GEOM_Object) aFillet;
3076 aFillet = myLocalOperations->MakeFilletEdges(aShape, theRF, theEdges);
3078 catch (Standard_Failure) {
3079 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3080 SetErrorCode(aFail->GetMessageString());
3083 if (aFillet.IsNull()) {
3084 SetErrorCode("Fillet can not be computed on the given shape with the given parameters");
3087 aFillet->GetLastFunction()->SetDescription("");
3089 TopoDS_Shape aFilletShape = aFillet->GetValue();
3090 aFunction->SetValue(aFilletShape);
3093 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (3)
3094 // the following block, when enabled, leads to partitioning problems
3096 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (3)
3097 // BEGIN: Limit tolerances (debug)
3098 Handle(GEOM_Object) aCorr1 = myHealingOperations->LimitTolerance(aShape, 1e-07);
3099 TopoDS_Shape aCorr1Shape = aCorr1->GetValue();
3100 aShape->GetLastFunction()->SetValue(aCorr1Shape);
3101 aCorr1->GetLastFunction()->SetDescription("");
3102 // END: Limit tolerances (debug)
3103 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - BEGIN (4)
3105 // VSR: debug issues 0021568 and 0021550 (15/05/2012) - END (4)
3108 if (!MakePipeTShapePartition(aShape, theR1, theW1, theL1, theR2, theW2, theL2, 0, 0, theRF, false))
3110 if (!MakePipeTShapeMirrorAndGlue(aShape, theR1, theW1, theL1, theR2, theW2, theL2))
3114 // Add thickness reduction elements
3115 // at the three extremities: Left, Right and Incident
3117 #if OCC_VERSION_LARGE > 0x06010000
3120 if (isTRL || isTRR || isTRI) {
3121 TopoDS_Shape aResShape =
3122 MakePipeTShapeThicknessReduction(aShape->GetValue(), theR1, theW1, theL1, theR2, theW2, theL2,
3123 theRL, theWL, theLtransL, theLthinL,
3124 theRR, theWR, theLtransR, theLthinR,
3125 theRI, theWI, theLtransI, theLthinI,
3127 aFunction->SetValue(aResShape);
3130 catch (Standard_Failure) {
3131 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3132 SetErrorCode(aFail->GetMessageString());
3137 gp_Trsf aTrsf = GetPositionTrsf(theL1, theL2, theP1, theP2, theP3);
3138 BRepBuilderAPI_Transform aTransformation (aShape->GetValue(), aTrsf, Standard_False);
3139 TopoDS_Shape aTrsf_Shape = aTransformation.Shape();
3140 aFunction->SetValue(aTrsf_Shape);
3142 Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
3143 aSeq->Append(aShape);
3148 if (!MakeGroups(aShape, TSHAPE_FILLET, theR1, theW1, theL1, theR2, theW2, theL2,
3149 0., 0., theRF, aSeq, aTrsf))
3153 // Get internal group.
3154 if (!MakeInternalGroup(aShape, theR1, theL1, theR2, theL2, theRL, theLtransL,
3155 theRR, theLtransR, theRI, theLtransI,
3160 catch (Standard_Failure) {
3161 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3162 SetErrorCode(aFail->GetMessageString());
3166 //Make a Python command
3167 TCollection_AsciiString anEntry, aListRes("[");
3168 // Iterate over the sequence aSeq
3169 Standard_Integer aNbGroups = aSeq->Length();
3170 Standard_Integer i = 1;
3171 for (; i <= aNbGroups; i++) {
3172 Handle(Standard_Transient) anItem = aSeq->Value(i);
3173 if (anItem.IsNull()) continue;
3174 Handle(GEOM_Object) aGroup = Handle(GEOM_Object)::DownCast(anItem);
3175 if (aGroup.IsNull()) continue;
3176 //Make a Python command
3177 TDF_Tool::Entry(aGroup->GetEntry(), anEntry);
3178 aListRes += anEntry + ", ";
3180 aListRes.Trunc(aListRes.Length() - 2);
3182 GEOM::TPythonDump pd (aFunction);
3184 pd << aListRes.ToCString() << "] = geompy.MakePipeTShapeFillet("
3185 << theR1 << ", " << theW1 << ", " << theL1 << ", "
3186 << theR2 << ", " << theW2 << ", " << theL2 << ", "
3187 << theRF << ", " << theHexMesh << ", "
3188 << theP1 << ", " << theP2 << ", " << theP3;
3190 // thickness reduction
3192 pd << ", theRL=" << theRL << ", theWL=" << theWL
3193 << ", theLtransL=" << theLtransL << ", theLthinL=" << theLthinL;
3195 pd << ", theRR=" << theRR << ", theWR=" << theWR
3196 << ", theLtransR=" << theLtransR << ", theLthinR=" << theLthinR;
3198 pd << ", theRI=" << theRI << ", theWI=" << theWI
3199 << ", theLtransI=" << theLtransI << ", theLthinI=" << theLthinI;
3208 //=============================================================================
3210 * This function allows to create a disk already divided into blocks. It can be
3211 * used to create divided pipes for later meshing in hexaedra.
3212 * \param theR Radius of the disk
3213 * \param theRatio Relative size of the central square diagonal against the disk diameter
3214 * \param theOrientation Plane on which the disk will be built
3215 * \param thePattern The division pattern of the disk (hexagon or square in the center)
3216 * \return New GEOM_Object, containing the created shape.
3218 //=============================================================================
3219 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedDisk (double theR, double theRatio,
3220 int theOrientation, int thePattern)
3224 if (theOrientation != 1 &&
3225 theOrientation != 2 &&
3226 theOrientation != 3)
3228 SetErrorCode("theOrientation must be 1(=OXY), 2(=OYZ) or 3(=OZX)");
3232 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3234 //Add a new shape function with parameters
3235 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_DividedDiskDriver::GetID(), DIVIDEDDISK_R_RATIO);
3236 if (aFunction.IsNull()) return NULL;
3238 //Check if the function is set correctly
3239 if (aFunction->GetDriverGUID() != GEOMImpl_DividedDiskDriver::GetID()) return NULL;
3241 GEOMImpl_IDividedDisk aData (aFunction);
3244 aData.SetRatio(theRatio);
3245 aData.SetOrientation(theOrientation);
3246 aData.SetType(thePattern);
3248 //Compute the resulting value
3250 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3253 if (!GetSolver()->ComputeFunction(aFunction)) {
3254 SetErrorCode("DividedDisk driver failed");
3258 catch (Standard_Failure) {
3259 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3260 SetErrorCode(aFail->GetMessageString());
3264 std::string aPatternStr;
3269 aPatternStr = "GEOM.SQUARE";
3272 aPatternStr = "GEOM.HEXAGON";
3276 //Make a Python command
3277 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDisk(" << theR << ", " << theOrientation << ", " << aPatternStr.c_str() << ")";
3284 //=============================================================================
3286 * This function allows to create a disk already divided into blocks. It can be
3287 * used to create divided pipes for later meshing in hexaedra.
3288 * \param theR Radius of the disk
3289 * \param theRatio Relative size of the central square diagonal against the disk diameter
3290 * \return New GEOM_Object, containing the created shape.
3292 //=============================================================================
3293 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedDiskPntVecR (Handle(GEOM_Object) thePnt,
3294 Handle(GEOM_Object) theVec,
3302 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDDISK);
3304 //Add a new shape function with parameters
3305 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_DividedDiskDriver::GetID(), DIVIDEDDISK_R_VECTOR_PNT);
3306 if (aFunction.IsNull()) return NULL;
3308 //Check if the function is set correctly
3309 if (aFunction->GetDriverGUID() != GEOMImpl_DividedDiskDriver::GetID()) return NULL;
3311 GEOMImpl_IDividedDisk aData (aFunction);
3313 Handle(GEOM_Function) aRefPnt = thePnt->GetLastFunction();
3314 Handle(GEOM_Function) aRefVec = theVec->GetLastFunction();
3316 if (aRefPnt.IsNull() || aRefVec.IsNull()) return NULL;
3318 aData.SetCenter(aRefPnt);
3319 aData.SetVector(aRefVec);
3322 aData.SetRatio(theRatio);
3323 aData.SetType(thePattern);
3325 //Compute the resulting value
3327 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3330 if (!GetSolver()->ComputeFunction(aFunction)) {
3331 SetErrorCode("DividedDisk driver failed");
3335 catch (Standard_Failure) {
3336 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3337 SetErrorCode(aFail->GetMessageString());
3341 std::string aPatternStr;
3346 aPatternStr = "GEOM.SQUARE";
3349 aPatternStr = "GEOM.HEXAGON";
3354 //Make a Python command
3355 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedDiskPntVecR(" << thePnt << ", " << theVec << ", " << theR << ", " << aPatternStr.c_str() << ")";
3362 //=============================================================================
3364 * Builds a cylinder prepared for hexa meshes
3365 * \param theR Radius of the cylinder
3366 * \param theH Height of the cylinder
3367 * \return New GEOM_Object, containing the created shape.
3369 //=============================================================================
3370 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeDividedCylinder (double theR,
3377 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_DIVIDEDCYLINDER);
3379 Handle(GEOM_Object) aBaseShape = MakeDividedDisk(theR, 67.0, 1, thePattern);
3380 aBaseShape->GetLastFunction()->SetDescription(""); // Erase dump of MakeDividedDisk
3382 aShape = my3DPrimOperations->MakePrismDXDYDZ(aBaseShape,0.0,0.0,theH, -1.0);
3384 Handle(GEOM_Function) aFunction = aShape->GetLastFunction();
3385 aFunction->SetDescription(""); // Erase dump of MakePrismDXDYDZ
3386 aShape->SetType(GEOM_DIVIDEDCYLINDER);
3388 std::string aPatternStr;
3393 aPatternStr = "GEOM.SQUARE";
3396 aPatternStr = "GEOM.HEXAGON";
3400 //Make a Python command
3401 GEOM::TPythonDump(aFunction) << aShape << " = geompy.MakeDividedCylinder(" << theR << ", " << theH << ", " << aPatternStr.c_str() << ")";
3407 //=============================================================================
3409 * Create a smoothing surface from a set of points
3410 * \param thelPoints list of points
3411 * \return New GEOM_Object, containing the created shape.
3413 //=============================================================================
3414 Handle(GEOM_Object) GEOMImpl_IAdvancedOperations::MakeSmoothingSurface (std::list<Handle(GEOM_Object)> thelPoints)
3419 Handle(GEOM_Object) aShape = GetEngine()->AddObject(GetDocID(), GEOM_SMOOTHINGSURFACE);
3421 //Add a new shape function with parameters
3422 Handle(GEOM_Function) aFunction = aShape->AddFunction(GEOMImpl_SmoothingSurfaceDriver::GetID(), SMOOTHINGSURFACE_LPOINTS);
3423 if (aFunction.IsNull()) return NULL;
3425 //Check if the function is set correctly
3426 if (aFunction->GetDriverGUID() != GEOMImpl_SmoothingSurfaceDriver::GetID()) return NULL;
3428 GEOMImpl_ISmoothingSurface aData (aFunction);
3430 int aLen = thelPoints.size();
3431 aData.SetLength(aLen);
3433 std::list<Handle(GEOM_Object)>::iterator it = thelPoints.begin();
3434 for (; it != thelPoints.end(); it++, ind++) {
3435 Handle(GEOM_Function) aRefPnt = (*it)->GetLastFunction();
3436 if (aRefPnt.IsNull()) {
3437 SetErrorCode("NULL point for bSplineFaceShape");
3440 aData.SetPoint(ind, aRefPnt);
3444 //Compute the resulting value
3446 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
3449 if (!GetSolver()->ComputeFunction(aFunction)) {
3450 SetErrorCode("SmoothingSurface driver failed");
3454 catch (Standard_Failure) {
3455 Handle(Standard_Failure) aFail = Standard_Failure::Caught();
3456 SetErrorCode(aFail->GetMessageString());
3460 //Make a Python command
3461 GEOM::TPythonDump pd (aFunction);
3462 pd << aShape << " = geompy.MakeSmoothingSurface([";
3463 it = thelPoints.begin();
3465 while (it != thelPoints.end()) {
3466 pd << ", " << (*it++);
3474 /*@@ insert new functions before this line @@ do not remove this line @@ do not remove this line @@*/