1 // Created on: 1998-11-12
2 // Created by: Robert COUBLANC
3 // Copyright (c) 1998-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #include <ViewerTest.hxx>
19 #include <AIS_AngleDimension.hxx>
20 #include <AIS_Circle.hxx>
21 #include <AIS_ConcentricRelation.hxx>
22 #include <AIS_DiameterDimension.hxx>
23 #include <AIS_DisplayMode.hxx>
24 #include <AIS_EqualDistanceRelation.hxx>
25 #include <AIS_EqualRadiusRelation.hxx>
26 #include <AIS_FixRelation.hxx>
27 #include <AIS_IdenticRelation.hxx>
28 #include <AIS_InteractiveContext.hxx>
29 #include <AIS_KindOfRelation.hxx>
30 #include <AIS_LengthDimension.hxx>
31 #include <AIS_ListIteratorOfListOfInteractive.hxx>
32 #include <AIS_ListOfInteractive.hxx>
33 #include <AIS_MapOfInteractive.hxx>
34 #include <AIS_OffsetDimension.hxx>
35 #include <AIS_ParallelRelation.hxx>
36 #include <AIS_PerpendicularRelation.hxx>
37 #include <AIS_Point.hxx>
38 #include <AIS_RadiusDimension.hxx>
39 #include <AIS_Relation.hxx>
40 #include <AIS_Shape.hxx>
41 #include <AIS_SymmetricRelation.hxx>
42 #include <AIS_TangentRelation.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BRep_Tool.hxx>
45 #include <BRepAdaptor_Curve.hxx>
46 #include <BRepBuilderAPI_MakeVertex.hxx>
47 #include <BRepExtrema_ExtCC.hxx>
48 #include <BRepExtrema_ExtPC.hxx>
49 #include <BRepExtrema_ExtCF.hxx>
50 #include <BRepExtrema_ExtPF.hxx>
51 #include <BRepExtrema_ExtFF.hxx>
52 #include <BRepTools.hxx>
53 #include <Draw_Interpretor.hxx>
55 #include <Draw_Appli.hxx>
56 #include <Draw_Window.hxx>
59 #include <Font_FontMgr.hxx>
60 #include <GC_MakePlane.hxx>
61 #include <Geom_CartesianPoint.hxx>
62 #include <Geom_Circle.hxx>
63 #include <Geom_Line.hxx>
64 #include <Geom_Plane.hxx>
65 #include <GeomAPI_IntCS.hxx>
66 #include <gce_MakeLin.hxx>
67 #include <gce_MakePln.hxx>
68 #include <gp_Circ.hxx>
70 #include <IntAna_IntConicQuad.hxx>
71 #include <IntAna_Quadric.hxx>
72 #include <Precision.hxx>
73 #include <StdSelect.hxx>
74 #include <TCollection_AsciiString.hxx>
75 #include <TCollection_ExtendedString.hxx>
76 #include <TColStd_MapOfInteger.hxx>
77 #include <TColStd_SequenceOfReal.hxx>
79 #include <TopAbs_ShapeEnum.hxx>
81 #include <TopExp_Explorer.hxx>
83 #include <TopoDS_Face.hxx>
84 #include <TopoDS_Solid.hxx>
85 #include <TopoDS_Vertex.hxx>
86 #include <V3d_Viewer.hxx>
87 #include <V3d_View.hxx>
89 #include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
90 #include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
91 #include <ViewerTest_EventManager.hxx>
92 #include <AIS_InteractiveObject.hxx>
93 #include <AIS_Dimension.hxx>
95 extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
96 const Handle(AIS_InteractiveObject)& theAISObj,
97 Standard_Boolean theReplaceIfExists = Standard_True);
98 extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
99 extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
100 extern Handle(AIS_InteractiveContext)& TheAISContext ();
102 #define VertexMask 0x01
103 #define EdgeMask 0x02
104 #define FaceMask 0x04
106 //=======================================================================
107 //function : Get3DPointAtMousePosition
108 //purpose : Calculates the 3D points corresponding to the mouse position
109 // in the plane of the view
110 //=======================================================================
111 static gp_Pnt Get3DPointAtMousePosition()
113 Handle(V3d_View) aView = ViewerTest::CurrentView();
115 Standard_Real xv,yv,zv;
116 aView->Proj (xv,yv,zv);
117 Standard_Real xat,yat,zat;
118 aView->At(xat,yat,zat);
119 gp_Pln aPlane (gp_Pnt(xat,yat,zat), gp_Dir(xv,yv,zv));
121 Standard_Integer aPixX, aPixY;
122 Standard_Real aX, aY, aZ, aDX, aDY, aDZ;
124 ViewerTest::GetMousePosition (aPixX, aPixY);
125 aView->ConvertWithProj (aPixX, aPixY, aX, aY, aZ, aDX, aDY, aDZ);
126 gp_Lin aLine( gp_Pnt(aX, aY, aZ), gp_Dir(aDX, aDY, aDZ) );
128 // Compute intersection
129 Handle(Geom_Line) aGeomLine = new Geom_Line (aLine);
130 Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
131 GeomAPI_IntCS anIntersector (aGeomLine, aGeomPlane);
132 if (!anIntersector.IsDone() || anIntersector.NbPoints() == 0)
136 return anIntersector.Point (1);
139 //=======================================================================
140 //function : Get3DPointAtMousePosition
141 //purpose : Calculates the 3D points corresponding to the mouse position
142 // in the plane of the view
143 //=======================================================================
144 static Standard_Boolean Get3DPointAtMousePosition (const gp_Pnt& theFirstPoint,
145 const gp_Pnt& theSecondPoint,
146 gp_Pnt& theOutputPoint)
148 theOutputPoint = gp::Origin();
150 Handle(V3d_View) aView = ViewerTest::CurrentView();
152 Standard_Integer aPixX, aPixY;
153 Standard_Real aX, aY, aZ, aDx, aDy, aDz, aUx, aUy, aUz;
155 // Get 3D point in view coordinates and projection vector from the pixel point.
156 ViewerTest::GetMousePosition (aPixX, aPixY);
157 aView->ConvertWithProj (aPixX, aPixY, aX, aY, aZ, aDx, aDy, aDz);
158 gp_Lin aProjLin (gp_Pnt(aX, aY, aZ), gp_Dir(aDx, aDy, aDz));
161 gp_Vec aDimVec (theFirstPoint, theSecondPoint);
162 aView->Up (aUx, aUy, aUz);
163 gp_Vec aViewUp (aUx, aUy, aUz);
165 if (aDimVec.IsParallel (aViewUp, Precision::Angular()))
167 theOutputPoint = Get3DPointAtMousePosition();
168 return Standard_True;
171 gp_Vec aDimNormal = aDimVec ^ aViewUp;
172 gp_Pln aViewPlane= gce_MakePln (theFirstPoint, aDimNormal);
174 // Get intersection of view plane and projection line
175 Handle(Geom_Plane) aPlane = new Geom_Plane (aViewPlane);
176 Handle(Geom_Line) aProjLine = new Geom_Line (aProjLin);
177 GeomAPI_IntCS anIntersector (aProjLine, aPlane);
178 if (!anIntersector.IsDone() || anIntersector.NbPoints() == 0)
180 return Standard_False;
183 theOutputPoint = anIntersector.Point (1);
184 return Standard_True;
187 //=======================================================================
188 //function : ParseDimensionParams
189 //purpose : Auxilliary function: sets aspect parameters for
190 // length, angle, radius and diameter dimension.
192 //draw args: -text [3d|2d] [wf|sh|wireframe|shading] [Size]
193 // -label [left|right|hcenter|hfit] [top|bottom|vcenter|vfit]
194 // -arrow [external|internal|fit] [Length(int)]
195 // -arrowangle ArrowAngle(degrees)
196 // -plane xoy|yoz|zox
197 // -flyout FloatValue -extension FloatValue
199 // -value CustomRealValue
200 // -textvalue CustomTextValue
201 // -dispunits DisplayUnitsString
202 // -modelunits ModelUnitsString
206 // Warning! flyout is not an aspect value, it is for dimension parameter
207 // likewise text position, but text position override other paramaters.
208 // For text position changing use 'vmovedim'.
209 //=======================================================================
210 static int ParseDimensionParams (Standard_Integer theArgNum,
211 const char** theArgVec,
212 Standard_Integer theStartIndex,
213 const Handle(Prs3d_DimensionAspect)& theAspect,
214 Standard_Boolean& theIsCustomPlane, gp_Pln& thePlane,
215 NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
216 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams,
217 NCollection_List<Handle(AIS_InteractiveObject)>* theShapeList = NULL)
219 theRealParams.Clear();
220 theStringParams.Clear();
222 theIsCustomPlane = Standard_False;
224 // Begin from the second parameter: the first one is dimension name
225 for (Standard_Integer anIt = theStartIndex; anIt < theArgNum; ++anIt)
227 TCollection_AsciiString aParam (theArgVec[anIt]);
230 if (aParam.Search ("-") == -1)
236 if (aParam.IsEqual ("-autovalue"))
238 theRealParams.Bind ("autovalue", 1);
242 if (aParam.IsEqual ("-showunits"))
244 theAspect->MakeUnitsDisplayed (Standard_True);
247 else if (aParam.IsEqual ("-hideunits"))
249 theAspect->MakeUnitsDisplayed (Standard_False);
252 else if (aParam.IsEqual ("-selected"))
256 std::cerr << "Error: unknown parameter '" << aParam << "'\n";
260 for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
262 TopoDS_Shape aShape = TheAISContext()->SelectedShape();
263 if (!aShape.IsNull())
265 theShapeList->Append (new AIS_Shape (aShape));
271 // Before all non-boolean flags parsing check if a flag have at least one value.
272 if (anIt + 1 >= theArgNum)
274 std::cerr << "Error: "<< aParam <<" flag should have value.\n";
279 if (aParam.IsEqual ("-shape")
280 || aParam.IsEqual ("-shapes"))
284 std::cerr << "Error: unknown parameter '" << aParam << "'\n";
291 TCollection_AsciiString anArgString = theArgVec[anIt];
292 Handle(AIS_InteractiveObject) anAISObject;
293 Standard_CString aStr = anArgString.ToCString();
294 TopoDS_Shape aShape = DBRep::Get (aStr);
295 if (!aShape.IsNull())
297 anAISObject = new AIS_Shape (aShape);
299 else if (!GetMapOfAIS().Find2 (anArgString, anAISObject)
300 || anAISObject.IsNull())
302 std::cerr << "Error: shape with name '" << aStr << "' is not found.\n";
305 theShapeList->Append (anAISObject);
307 while (anIt + 1 < theArgNum && theArgVec[anIt + 1][0] != '-');
309 else if (aParam.IsEqual ("-text"))
314 TCollection_AsciiString aValue (theArgVec[anIt]);
316 if (aValue.IsEqual ("3d"))
318 theAspect->MakeText3d (Standard_True);
320 else if (aValue.IsEqual ("2d"))
322 theAspect->MakeText3d (Standard_False);
324 else if (aValue.IsEqual ("wf") || aValue.IsEqual ("wireframe"))
326 theAspect->MakeTextShaded (Standard_False);
328 else if ( aValue.IsEqual ("sh") || aValue.IsEqual ("shading"))
330 theAspect->MakeTextShaded (Standard_True);
332 else if (aValue.IsIntegerValue()) // text size
334 theAspect->TextAspect()->SetHeight (Draw::Atoi (aValue.ToCString()));
337 while (anIt + 1 < theArgNum && theArgVec[anIt + 1][0] != '-');
339 else if (aParam.IsEqual ("-font"))
341 if (anIt + 1 >= theArgNum)
343 std::cout << "Error: wrong number of values for parameter '" << aParam << "'.\n";
347 theAspect->TextAspect()->SetFont (theArgVec[++anIt]);
349 else if (aParam.IsEqual ("-label"))
354 TCollection_AsciiString aParamValue (theArgVec[anIt]);
355 aParamValue.LowerCase();
357 if (aParamValue == "left") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Left); }
358 else if (aParamValue == "right") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Right); }
359 else if (aParamValue == "hcenter") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Center);}
360 else if (aParamValue == "hfit") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Fit); }
361 else if (aParamValue == "above") { theAspect->SetTextVerticalPosition (Prs3d_DTVP_Above); }
362 else if (aParamValue == "below") { theAspect->SetTextVerticalPosition (Prs3d_DTVP_Below); }
363 else if (aParamValue == "vcenter") { theAspect->SetTextVerticalPosition (Prs3d_DTVP_Center);}
366 std::cerr << "Error: invalid label position: '" << aParamValue << "'.\n";
370 while (anIt + 1 < theArgNum && theArgVec[anIt+1][0] != '-');
372 else if (aParam.IsEqual ("-arrow"))
374 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
375 aLocalParam.LowerCase();
377 if (aLocalParam == "external") { theAspect->SetArrowOrientation (Prs3d_DAO_External); }
378 if (aLocalParam == "internal") { theAspect->SetArrowOrientation (Prs3d_DAO_Internal); }
379 if (aLocalParam == "fit") { theAspect->SetArrowOrientation (Prs3d_DAO_Fit); }
381 else if (aParam.IsEqual ("-arrowlength") || aParam.IsEqual ("-arlen"))
383 TCollection_AsciiString aValue (theArgVec[++anIt]);
384 if (!aValue.IsRealValue())
386 std::cerr << "Error: arrow lenght should be float degree value.\n";
389 theAspect->ArrowAspect()->SetLength (Draw::Atof (aValue.ToCString()));
391 else if (aParam.IsEqual ("-arrowangle") || aParam.IsEqual ("-arangle"))
393 TCollection_AsciiString aValue (theArgVec[++anIt]);
394 if (!aValue.IsRealValue())
396 std::cerr << "Error: arrow angle should be float degree value.\n";
399 theAspect->ArrowAspect()->SetAngle (Draw::Atof (aValue.ToCString()));
401 else if (aParam.IsEqual ("-color"))
403 theAspect->SetCommonColor (Quantity_Color (ViewerTest::GetColorFromName (theArgVec[++anIt])));
405 else if (aParam.IsEqual ("-extension"))
407 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
408 if (!aLocalParam.IsRealValue())
410 std::cerr << "Error: extension size for dimension should be real value.\n";
413 theAspect->SetExtensionSize (Draw::Atof (aLocalParam.ToCString()));
415 else if (aParam.IsEqual ("-plane"))
417 TCollection_AsciiString aValue (theArgVec[++anIt]);
421 theIsCustomPlane = Standard_True;
422 thePlane = gp_Pln (gp_Ax3 (gp::XOY()));
424 else if (aValue == "zox")
426 theIsCustomPlane = Standard_True;
427 thePlane = gp_Pln (gp_Ax3 (gp::ZOX()));
429 else if (aValue == "yoz")
431 theIsCustomPlane = Standard_True;
432 thePlane = gp_Pln (gp_Ax3 (gp::YOZ()));
436 std::cerr << "Error: wrong plane '" << aValue << "'.\n";
440 else if (aParam.IsEqual ("-flyout"))
442 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
443 if (!aLocalParam.IsRealValue())
445 std::cerr << "Error: flyout for dimension should be real value.\n";
449 theRealParams.Bind ("flyout", Draw::Atof (aLocalParam.ToCString()));
451 else if (aParam.IsEqual ("-value"))
453 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
454 if (!aLocalParam.IsRealValue())
456 std::cerr << "Error: dimension value for dimension should be real value.\n";
460 theRealParams.Bind ("value", Draw::Atof (aLocalParam.ToCString()));
462 else if (aParam.IsEqual ("-textvalue"))
464 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
466 theStringParams.Bind ("textvalue", aLocalParam);
468 else if (aParam.IsEqual ("-modelunits"))
470 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
472 theStringParams.Bind ("modelunits", aLocalParam);
474 else if (aParam.IsEqual ("-dispunits"))
476 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
478 theStringParams.Bind ("dispunits", aLocalParam);
482 std::cerr << "Error: unknown parameter '" << aParam << "'.\n";
490 //=======================================================================
491 //function : SetDimensionParams
492 //purpose : Sets parameters for dimension
493 //=======================================================================
494 static void SetDimensionParams (const Handle(AIS_Dimension)& theDim,
495 const NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
496 const NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams)
498 if (theRealParams.IsBound ("flyout"))
500 theDim->SetFlyout (theRealParams.Find ("flyout"));
503 if (theRealParams.IsBound ("autovalue"))
505 theDim->SetComputedValue();
508 if (theRealParams.IsBound ("value"))
510 theDim->SetCustomValue (theRealParams.Find ("value"));
513 if (theStringParams.IsBound ("textvalue"))
515 theDim->SetCustomValue (theStringParams.Find ("textvalue"));
518 if (theStringParams.IsBound ("modelunits"))
520 theDim->SetModelUnits (theStringParams.Find ("modelunits"));
523 if (theStringParams.IsBound ("dispunits"))
525 theDim->SetDisplayUnits (theStringParams.Find ("dispunits"));
529 //=======================================================================
530 //function : ParseAngleDimensionParams
531 //purpose : Auxilliary function: sets custom parameters for angle dimension.
533 //draw args: -type [interior|exterior]
534 // -showarrow [first|second|both|none]
535 //=======================================================================
536 static int ParseAngleDimensionParams (Standard_Integer theArgNum,
537 const char** theArgVec,
538 Standard_Integer theStartIndex,
539 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams)
541 theStringParams.Clear();
543 // Begin from the second parameter: the first one is dimension name
544 for (Standard_Integer anIt = theStartIndex; anIt < theArgNum; ++anIt)
546 TCollection_AsciiString aParam (theArgVec[anIt]);
549 if (aParam.Search ("-") == -1)
551 std::cerr << "Error: wrong parameter '" << aParam << "'.\n";
555 // Before all non-boolean flags parsing check if a flag have at least one value.
556 if (anIt + 1 >= theArgNum)
558 std::cerr << "Error: "<< aParam <<" flag should have value.\n";
562 if (aParam.IsEqual ("-type"))
564 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
566 theStringParams.Bind ("type", aLocalParam);
568 else if (aParam.IsEqual ("-showarrow"))
570 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
572 theStringParams.Bind ("showarrow", aLocalParam);
576 std::cerr << "Error: unknown parameter '" << aParam << "'.\n";
584 //=======================================================================
585 //function : SetAngleDimensionParams
586 //purpose : Sets parameters for angle dimension
587 //=======================================================================
588 static void SetAngleDimensionParams (const Handle(AIS_Dimension)& theDim,
589 const NCollection_DataMap<TCollection_AsciiString,
590 TCollection_AsciiString>& theStringParams)
592 Handle(AIS_AngleDimension) anAngleDim = Handle(AIS_AngleDimension)::DownCast (theDim);
593 if (anAngleDim.IsNull())
598 if (theStringParams.IsBound ("type"))
600 AIS_TypeOfAngle anAngleType = AIS_TOA_Interior;
601 TCollection_AsciiString anAngleTypeStr = theStringParams.Find ("type");
602 if (anAngleTypeStr.IsEqual("interior"))
604 anAngleType = AIS_TOA_Interior;
606 else if (anAngleTypeStr.IsEqual("exterior"))
608 anAngleType = AIS_TOA_Exterior;
612 std::cerr << "Error: wrong angle type.\n";
614 anAngleDim->SetType(anAngleType);
617 if (theStringParams.IsBound ("showarrow"))
619 AIS_TypeOfAngleArrowVisibility anArrowType = AIS_TOAV_Both;
620 TCollection_AsciiString anArrowTypeStr = theStringParams.Find ("showarrow");
621 if (anArrowTypeStr.IsEqual("both"))
623 anArrowType = AIS_TOAV_Both;
625 else if (anArrowTypeStr.IsEqual("first"))
627 anArrowType = AIS_TOAV_First;
629 else if (anArrowTypeStr.IsEqual("second"))
631 anArrowType = AIS_TOAV_Second;
633 else if (anArrowTypeStr.IsEqual("none"))
635 anArrowType = AIS_TOAV_None;
639 std::cerr << "Error: wrong showarrow type.\n";
641 anAngleDim->SetArrowsVisibility(anArrowType);
645 //=======================================================================
646 //function : VDimBuilder
647 //purpose : Command for building dimension presentations: angle,
648 // length, radius, diameter
649 //=======================================================================
650 static int VDimBuilder (Draw_Interpretor& /*theDi*/,
651 Standard_Integer theArgsNb,
652 const char** theArgs)
656 std::cerr << "Error: wrong number of arguments.\n";
661 TCollection_AsciiString aName (theArgs[1]);
663 NCollection_List<Handle(AIS_InteractiveObject)> aShapes;
664 Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect;
665 Standard_Boolean isPlaneCustom = Standard_False;
666 gp_Pln aWorkingPlane;
668 NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
669 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
671 TCollection_AsciiString aDimType(theArgs[2]);
672 aDimType.LowerCase();
673 AIS_KindOfDimension aKindOfDimension;
674 if (aDimType == "-length")
676 aKindOfDimension = AIS_KOD_LENGTH;
678 else if (aDimType == "-angle")
680 aKindOfDimension = AIS_KOD_PLANEANGLE;
682 else if (aDimType == "-radius")
684 aKindOfDimension = AIS_KOD_RADIUS;
686 else if (aDimType == "-diameter" || aDimType == "-diam")
688 aKindOfDimension = AIS_KOD_DIAMETER;
692 std::cerr << "Error: wrong type of dimension.\n";
697 if (ParseDimensionParams (theArgsNb, theArgs, 3,
698 anAspect,isPlaneCustom,aWorkingPlane,
699 aRealParams, aStringParams, &aShapes))
705 Handle(AIS_Dimension) aDim;
706 switch (aKindOfDimension)
710 if (aShapes.Extent() == 1)
712 if (aShapes.First()->Type() == AIS_KOI_Shape
713 && (Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape().ShapeType() != TopAbs_EDGE)
715 std::cerr << theArgs[0] << ": wrong shape type.\n";
720 std::cerr << theArgs[0] << ": can not build dimension without working plane.\n";
724 // Adjust working plane
725 TopoDS_Edge anEdge = TopoDS::Edge ((Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape());
726 TopoDS_Vertex aFirst, aSecond;
727 TopExp::Vertices (anEdge, aFirst, aSecond);
728 aDim = new AIS_LengthDimension (anEdge, aWorkingPlane);
730 // Move standard plane (XOY, YOZ or ZOX) to the first point to make it working for dimension
731 aWorkingPlane.SetLocation (Handle(AIS_LengthDimension)::DownCast (aDim)->FirstPoint());
733 else if (aShapes.Extent() == 2)
735 TopoDS_Shape aShape1, aShape2;
738 if (aShapes.First()->DynamicType() == STANDARD_TYPE (AIS_Point))
740 aShape1 = Handle(AIS_Point)::DownCast (aShapes.First ())->Vertex();
742 else if (aShapes.First()->Type() == AIS_KOI_Shape)
744 aShape1 = (Handle(AIS_Shape)::DownCast (aShapes.First()))->Shape();
747 if (aShapes.Last()->DynamicType() == STANDARD_TYPE (AIS_Point))
749 aShape2 = Handle(AIS_Point)::DownCast (aShapes.Last ())->Vertex();
751 else if (aShapes.Last()->Type() == AIS_KOI_Shape)
753 aShape2 = (Handle(AIS_Shape)::DownCast (aShapes.Last()))->Shape();
756 if (aShape1.IsNull() || aShape2.IsNull())
758 std::cerr << theArgs[0] << ": wrong shape type.\n";
763 if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_FACE)
765 aDim = new AIS_LengthDimension (TopoDS::Face (aShape1), TopoDS::Face (aShape2));
767 else if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_EDGE)
769 aDim = new AIS_LengthDimension (TopoDS::Face (aShape1), TopoDS::Edge (aShape2));
771 else if (aShape1.ShapeType() == TopAbs_EDGE && aShape2.ShapeType() == TopAbs_FACE)
773 aDim = new AIS_LengthDimension (TopoDS::Face (aShape2), TopoDS::Edge (aShape1));
779 std::cerr << theArgs[0] << ": can not build dimension without working plane.\n";
782 // Vertex-Vertex case
783 if (aShape1.ShapeType() == TopAbs_VERTEX)
785 aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape1)));
787 else if (aShape2.ShapeType() == TopAbs_VERTEX)
789 aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape2)));
792 aDim = new AIS_LengthDimension (aShape1, aShape2, aWorkingPlane);
797 std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
803 case AIS_KOD_PLANEANGLE:
805 if (aShapes.Extent() == 1 && aShapes.First()->Type()==AIS_KOI_Shape)
807 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aShapes.First());
808 if (aShape->Shape().ShapeType() == TopAbs_FACE)
809 aDim = new AIS_AngleDimension (TopoDS::Face(aShape->Shape()));
811 if (aShapes.Extent() == 2)
813 Handle(AIS_Shape) aShape1 = Handle(AIS_Shape)::DownCast(aShapes.First());
814 Handle(AIS_Shape) aShape2 = Handle(AIS_Shape)::DownCast(aShapes.Last());
815 if (!aShape1.IsNull() && !aShape2.IsNull()
816 && aShape1->Shape().ShapeType() == TopAbs_EDGE
817 && aShape2->Shape().ShapeType() == TopAbs_EDGE)
818 aDim = new AIS_AngleDimension (TopoDS::Edge(aShape1->Shape()),TopoDS::Edge(aShape2->Shape()));
821 std::cerr << theArgs[0] << ": wrong shapes for angle dimension.\n";
825 else if (aShapes.Extent() == 3)
827 gp_Pnt aP1, aP2, aP3;
828 Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
831 aP1 = aPoint->Component()->Pnt();
832 aShapes.RemoveFirst();
833 aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
836 aP2 = aPoint->Component()->Pnt();
837 aShapes.RemoveFirst();
838 aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
841 aP3 = aPoint->Component()->Pnt();
842 aDim = new AIS_AngleDimension (aP1, aP2, aP3);
846 std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
852 case AIS_KOD_RADIUS: // radius of the circle
855 bool hasAnchor = false;
856 for (NCollection_List<Handle(AIS_InteractiveObject)>::Iterator aShapeIter (aShapes); aShapeIter.More(); aShapeIter.Next())
858 if (Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(aShapeIter.Value()))
861 anAnchor = aPoint->Component()->Pnt();
862 aShapes.Remove (aShapeIter);
866 if (aShapes.Extent() != 1)
868 std::cout << "Syntax error: wrong number of shapes to build dimension.\n";
872 if (Handle(AIS_Circle) aShapeCirc = Handle(AIS_Circle)::DownCast(aShapes.First()))
874 gp_Circ aCircle = aShapeCirc->Circle()->Circ();
877 aDim = new AIS_RadiusDimension (aCircle, anAnchor);
881 aDim = new AIS_RadiusDimension (aCircle);
884 else if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aShapes.First()))
886 Handle(AIS_RadiusDimension) aRadDim = new AIS_RadiusDimension (aShape->Shape());
889 aRadDim->SetMeasuredGeometry (aShape->Shape(), anAnchor);
895 std::cout << "Error: shape for radius has wrong type.\n";
900 case AIS_KOD_DIAMETER:
902 if (aShapes.Extent() == 1)
904 if (aShapes.First()->DynamicType() == STANDARD_TYPE(AIS_Circle))
906 Handle(AIS_Circle) aShape = Handle(AIS_Circle)::DownCast (aShapes.First());
907 gp_Circ aCircle = aShape->Circle()->Circ();
908 aDim = new AIS_DiameterDimension (aCircle);
912 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aShapes.First());
915 std::cerr << "Error: shape for radius is of wrong type.\n";
918 aDim = new AIS_DiameterDimension (aShape->Shape());
923 std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
931 std::cerr << theArgs[0] << ": wrong type of dimension. Type help for more information.\n";
936 // Check dimension geometry
937 if (!aDim->IsValid())
939 std::cerr << theArgs[0] << ":dimension geometry is invalid, " << aDimType.ToCString()
940 << " dimension can't be built on input shapes.\n";
944 aDim->SetDimensionAspect (anAspect);
946 SetDimensionParams (aDim, aRealParams, aStringParams);
948 VDisplayAISObject (aName,aDim);
955 //! If the given shapes are edges then check whether they are parallel else return true.
956 Standard_Boolean IsParallel (const TopoDS_Shape& theShape1,
957 const TopoDS_Shape& theShape2)
959 if (theShape1.ShapeType() == TopAbs_EDGE
960 && theShape2.ShapeType() == TopAbs_EDGE)
962 BRepExtrema_ExtCC aDelta (TopoDS::Edge (theShape1),
963 TopoDS::Edge (theShape2));
964 return aDelta.IsParallel();
967 return Standard_True;
970 //=======================================================================
971 //function : VRelationBuilder
972 //purpose : Command for building realation presentation
973 //=======================================================================
974 static int VRelationBuilder (Draw_Interpretor& /*theDi*/,
975 Standard_Integer theArgsNb,
976 const char** theArgs)
980 std::cerr << "Error: wrong number of arguments.\n";
984 TCollection_AsciiString aName (theArgs[1]);
985 TCollection_AsciiString aType (theArgs[2]);
987 AIS_KindOfRelation aKindOfRelation = AIS_KOR_NONE;
988 if (aType == "-concentric")
990 aKindOfRelation = AIS_KOR_CONCENTRIC;
992 else if (aType == "-equaldistance")
994 aKindOfRelation = AIS_KOR_EQUALDISTANCE;
996 else if (aType == "-equalradius")
998 aKindOfRelation = AIS_KOR_EQUALRADIUS;
1000 else if (aType == "-fix")
1002 aKindOfRelation = AIS_KOR_FIX;
1004 else if (aType == "-identic")
1006 aKindOfRelation = AIS_KOR_IDENTIC;
1008 else if (aType == "-offset")
1010 aKindOfRelation = AIS_KOR_OFFSET;
1012 else if (aType == "-parallel")
1014 aKindOfRelation = AIS_KOR_PARALLEL;
1016 else if (aType == "-perpendicular")
1018 aKindOfRelation = AIS_KOR_PERPENDICULAR;
1020 else if (aType == "-tangent")
1022 aKindOfRelation = AIS_KOR_TANGENT;
1024 else if (aType == "-symmetric")
1026 aKindOfRelation = AIS_KOR_SYMMETRIC;
1029 TopTools_ListOfShape aShapes;
1030 ViewerTest::GetSelectedShapes (aShapes);
1033 Handle(AIS_Relation) aRelation;
1034 switch (aKindOfRelation)
1036 case AIS_KOR_CONCENTRIC:
1038 if (aShapes.Extent() != 2)
1040 std::cerr << "Error: Wrong number of selected shapes.\n";
1044 const TopoDS_Shape& aShape1 = aShapes.First();
1045 const TopoDS_Shape& aShape2 = aShapes.Last();
1047 if (!(aShape1.ShapeType() == TopAbs_EDGE
1048 && aShape2.ShapeType() == TopAbs_EDGE))
1050 std::cerr << "Syntax error: selected shapes are not edges.\n";
1054 BRepAdaptor_Curve aCurve1 (TopoDS::Edge (aShape1));
1055 gp_Circ aCircle1 = aCurve1.Circle();
1056 gp_Pnt aCenter1 = aCircle1.Location();
1057 gp_Pnt B = aCurve1.Value (0.25);
1058 gp_Pnt C = aCurve1.Value (0.75);
1059 GC_MakePlane aMkPlane (aCenter1, B, C);
1061 aRelation = new AIS_ConcentricRelation (aShape1, aShape2, aMkPlane.Value());
1066 case AIS_KOR_EQUALDISTANCE:
1068 if (aShapes.Extent() != 4)
1070 std::cerr << "Error: Wrong number of selected shapes.\n";
1074 TopoDS_Shape aSelectedShapes[4];
1076 Standard_Integer anIdx = 0;
1077 TopTools_ListOfShape::Iterator anIter (aShapes);
1078 for (; anIter.More(); anIter.Next(), ++anIdx)
1080 aSelectedShapes[anIdx] = anIter.Value();
1083 if (!IsParallel (aSelectedShapes[0], aSelectedShapes[1])
1084 || !IsParallel (aSelectedShapes[2], aSelectedShapes[3]))
1086 std::cerr << "Syntax error: non parallel edges.\n";
1091 if (aSelectedShapes[0].ShapeType() == TopAbs_EDGE)
1093 TopoDS_Vertex Va, Vb;
1094 TopExp::Vertices (TopoDS::Edge (aSelectedShapes[0]), Va, Vb);
1095 A = BRep_Tool::Pnt (Va);
1096 B = BRep_Tool::Pnt (Vb);
1098 if (aSelectedShapes[1].ShapeType() == TopAbs_EDGE)
1100 TopoDS_Vertex Vc, Vd;
1101 TopExp::Vertices (TopoDS::Edge (aSelectedShapes[1]), Vc, Vd);
1102 C = BRep_Tool::Pnt (Vc);
1106 C = BRep_Tool::Pnt (TopoDS::Vertex (aSelectedShapes[1]));
1111 A = BRep_Tool::Pnt (TopoDS::Vertex (aSelectedShapes[0]));
1113 if (aSelectedShapes[1].ShapeType() == TopAbs_EDGE)
1115 TopoDS_Vertex Vb, Vc;
1116 TopExp::Vertices (TopoDS::Edge (aSelectedShapes[1]), Vb, Vc);
1117 B = BRep_Tool::Pnt (Vb);
1118 C = BRep_Tool::Pnt (Vc);
1123 B = BRep_Tool::Pnt (TopoDS::Vertex (aSelectedShapes[1]));
1124 C.SetX (B.X() + 5.0);
1125 C.SetY (B.Y() + 5.0);
1126 C.SetZ (B.Z() + 5.0);
1131 GC_MakePlane aMkPlane (A, B, C);
1132 aRelation = new AIS_EqualDistanceRelation (aSelectedShapes[0],
1141 case AIS_KOR_EQUALRADIUS:
1143 if (aShapes.Extent() != 2 && aShapes.Extent() != 1)
1145 std::cerr << "Error: Wrong number of selected shapes.\n";
1149 const TopoDS_Shape& aShape1 = aShapes.First();
1150 const TopoDS_Shape& aShape2 = (aShapes.Extent() == 2) ? aShapes.Last() : aShape1;
1151 if (!(aShape1.ShapeType() == TopAbs_EDGE
1152 && aShape2.ShapeType() == TopAbs_EDGE))
1154 std::cerr << "Syntax error: selected shapes are not edges.\n";
1158 TopoDS_Edge anEdge1 = TopoDS::Edge (aShape1);
1159 TopoDS_Edge anEdge2 = TopoDS::Edge (aShape2);
1160 BRepAdaptor_Curve aCurve1 (anEdge1);
1161 gp_Pnt A = aCurve1.Value (0.1);
1162 gp_Pnt B = aCurve1.Value (0.5);
1163 gp_Pnt C = aCurve1.Value (0.9);
1164 GC_MakePlane aMkPlane (A, B, C);
1166 aRelation = new AIS_EqualRadiusRelation (anEdge1, anEdge2, aMkPlane.Value());
1172 if (aShapes.Extent() != 1)
1174 std::cerr << "Error: Wrong number of selected shapes.\n";
1178 const TopoDS_Shape& aShape = aShapes.First();
1179 if (aShape.ShapeType() != TopAbs_EDGE)
1181 std::cerr << "Syntax error: selected shapes are not edges.\n";
1185 TopoDS_Edge anEdge = TopoDS::Edge (aShape);
1186 BRepAdaptor_Curve aCurve (anEdge);
1187 gp_Pnt A = aCurve.Value(0.1);
1188 gp_Pnt B = aCurve.Value(0.5);
1189 gp_Pnt D = aCurve.Value(0.9);
1190 gp_Pnt C (B.X() + 5.0, B.Y() + 5.0, B.Z() + 5.0);
1191 GC_MakePlane aMkPlane (A, D, C);
1193 aRelation = new AIS_FixRelation (anEdge, aMkPlane.Value());
1197 case AIS_KOR_IDENTIC:
1199 if (aShapes.Extent() != 2)
1201 std::cerr << "Error: Wrong number of selected shapes.\n";
1205 const TopoDS_Shape& aShapeA = aShapes.First();
1206 const TopoDS_Shape& aShapeB = aShapes.Last();
1209 if (aShapeA.ShapeType() == TopAbs_EDGE)
1211 TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
1212 BRepAdaptor_Curve aCurveA (anEdgeA);
1214 A = aCurveA.Value (0.1);
1215 B = aCurveA.Value (0.9);
1216 C.SetX (B.X() + 5.0);
1217 C.SetY (B.Y() + 5.0);
1218 C.SetZ (B.Z() + 5.0);
1220 else if (aShapeA.ShapeType() == TopAbs_VERTEX)
1222 if (aShapeB.ShapeType() == TopAbs_EDGE)
1224 TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
1225 BRepAdaptor_Curve aCurveB (anEdgeB);
1227 A = aCurveB.Value (0.1);
1228 B = aCurveB.Value (0.9);
1229 C.SetX (B.X() + 5.0);
1230 C.SetY (B.Y() + 5.0);
1231 C.SetZ (B.Z() + 5.0);
1233 else if (aShapeB.ShapeType() == TopAbs_FACE)
1235 TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
1236 TopExp_Explorer aFaceExp (aFaceB, TopAbs_EDGE);
1237 TopoDS_Edge anEdgeFromB = TopoDS::Edge (aFaceExp.Current());
1238 BRepAdaptor_Curve aCurveB (anEdgeFromB);
1239 A = aCurveB.Value (0.1);
1240 B = aCurveB.Value (0.5);
1241 C = aCurveB.Value (0.9);
1245 A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
1246 B = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
1247 C.SetX (B.X() + 5.0);
1248 C.SetY (B.Y() + 5.0);
1249 C.SetZ (B.Z() + 5.0);
1254 TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
1255 TopExp_Explorer aFaceExp (aFaceA, TopAbs_EDGE);
1256 TopoDS_Edge anEdgeFromA = TopoDS::Edge (aFaceExp.Current());
1257 BRepAdaptor_Curve aCurveA (anEdgeFromA);
1258 A = aCurveA.Value (0.1);
1259 B = aCurveA.Value (0.5);
1260 C = aCurveA.Value (0.9);
1263 GC_MakePlane aMkPlane (A ,B ,C);
1264 aRelation = new AIS_IdenticRelation (aShapeA, aShapeB, aMkPlane.Value());
1268 case AIS_KOR_OFFSET:
1270 if (aShapes.Extent() != 2)
1272 std::cerr << "Error: Wrong number of selected shapes.\n";
1276 const TopoDS_Shape& aShape1 = aShapes.First();
1277 const TopoDS_Shape& aShape2 = aShapes.Last();
1278 if (!(aShape1.ShapeType() == TopAbs_FACE
1279 && aShape2.ShapeType() == TopAbs_FACE))
1281 std::cerr << "Syntax error: selected shapes are not faces.\n";
1285 TopoDS_Face aFace1 = TopoDS::Face (aShape1);
1286 TopoDS_Face aFace2 = TopoDS::Face (aShape2);
1288 BRepExtrema_ExtFF aDelta (aFace1, aFace2);
1289 if (!aDelta.IsParallel())
1291 std::cerr << "Syntax error: the faces are not parallel.\n";
1295 Standard_Real aDist = Round (sqrt (aDelta.SquareDistance (1)) * 10.0) / 10.0;
1296 TCollection_ExtendedString aMessage (TCollection_ExtendedString ("offset=") + TCollection_ExtendedString (aDist));
1298 aRelation = new AIS_OffsetDimension (aFace1, aFace2, aDist, aMessage);
1303 case AIS_KOR_PARALLEL:
1305 if (aShapes.Extent() != 2)
1307 std::cerr << "Error: wrong number of selected shapes.\n";
1311 const TopoDS_Shape& aShapeA = aShapes.First();
1312 const TopoDS_Shape& aShapeB = aShapes.Last();
1313 if (aShapeA.ShapeType() == TopAbs_EDGE)
1315 TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
1316 TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
1317 BRepExtrema_ExtCC aDeltaEdge (anEdgeA, anEdgeB);
1319 if (!aDeltaEdge.IsParallel())
1321 std::cerr << "Error: the edges are not parallel.\n";
1325 BRepAdaptor_Curve aCurveA (anEdgeA);
1326 BRepAdaptor_Curve aCurveB (anEdgeB);
1328 gp_Pnt A = aCurveA.Value (0.1);
1329 gp_Pnt B = aCurveA.Value (0.9);
1330 gp_Pnt C = aCurveB.Value (0.5);
1332 GC_MakePlane aMkPlane (A, B, C);
1334 aRelation = new AIS_ParallelRelation (anEdgeA, anEdgeB, aMkPlane.Value());
1338 TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
1339 TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
1341 BRepExtrema_ExtFF aDeltaFace (aFaceA, aFaceB);
1342 if (!aDeltaFace.IsParallel())
1344 std::cerr << "Error: the faces are not parallel.\n";
1348 TopExp_Explorer aFaceExpA (aFaceA, TopAbs_EDGE);
1349 TopExp_Explorer aFaceExpB (aFaceB, TopAbs_EDGE);
1351 TopoDS_Edge anEdgeA = TopoDS::Edge (aFaceExpA.Current());
1352 TopoDS_Edge anEdgeB = TopoDS::Edge (aFaceExpB.Current());
1354 BRepAdaptor_Curve aCurveA (anEdgeA);
1355 BRepAdaptor_Curve aCurveB (anEdgeB);
1356 gp_Pnt A = aCurveA.Value (0.1);
1357 gp_Pnt B = aCurveA.Value (0.9);
1358 gp_Pnt C = aCurveB.Value (0.5);
1360 GC_MakePlane aMkPlane (A, B, C);
1362 aRelation = new AIS_ParallelRelation (aFaceA, aFaceB, aMkPlane.Value());
1367 case AIS_KOR_PERPENDICULAR:
1369 if (aShapes.Extent() != 2)
1371 std::cerr << "Error: Wrong number of selected shapes.\n";
1375 const TopoDS_Shape& aShapeA = aShapes.First();
1376 const TopoDS_Shape& aShapeB = aShapes.Last();
1378 if (aShapeA.ShapeType() == TopAbs_EDGE)
1380 TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
1381 TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
1383 BRepAdaptor_Curve aCurveA (anEdgeA);
1384 BRepAdaptor_Curve aCurveB (anEdgeB);
1386 gp_Pnt A = aCurveA.Value (0.1);
1387 gp_Pnt B = aCurveA.Value (0.9);
1388 gp_Pnt C = aCurveB.Value (0.5);
1390 GC_MakePlane aMkPlane (A, B, C);
1392 aRelation = new AIS_PerpendicularRelation (anEdgeA, anEdgeB, aMkPlane.Value());
1396 TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
1397 TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
1399 TopExp_Explorer aFaceExpA (aFaceA, TopAbs_EDGE);
1400 TopExp_Explorer aFaceExpB (aFaceB, TopAbs_EDGE);
1402 TopoDS_Edge anEdgeA = TopoDS::Edge (aFaceExpA.Current());
1403 TopoDS_Edge anEdgeB = TopoDS::Edge (aFaceExpB.Current());
1405 BRepAdaptor_Curve aCurveA (anEdgeA);
1406 BRepAdaptor_Curve aCurveB (anEdgeB);
1408 gp_Pnt A = aCurveA.Value (0.1);
1409 gp_Pnt B = aCurveA.Value (0.9);
1410 gp_Pnt C = aCurveB.Value (0.5);
1412 GC_MakePlane aMkPlane (A, B, C);
1414 aRelation = new AIS_PerpendicularRelation (aFaceA, aFaceB);
1420 case AIS_KOR_TANGENT:
1422 if (aShapes.Extent() != 2)
1424 std::cerr << "Error: Wrong number of selected shapes.\n";
1428 const TopoDS_Shape& aShapeA = aShapes.First();
1429 const TopoDS_Shape& aShapeB = aShapes.Last();
1431 if (aShapeA.ShapeType() == TopAbs_EDGE)
1433 TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
1434 TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
1436 BRepAdaptor_Curve aCurveA (anEdgeA);
1437 BRepAdaptor_Curve aCurveB (anEdgeB);
1439 gp_Pnt A = aCurveA.Value (0.1);
1440 gp_Pnt B = aCurveA.Value (0.9);
1441 gp_Pnt C = aCurveB.Value (0.5);
1443 GC_MakePlane aMkPlane (A,B,C);
1445 aRelation = new AIS_TangentRelation (anEdgeA, anEdgeB, aMkPlane.Value());
1449 TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
1450 TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
1452 TopExp_Explorer aFaceExpA (aFaceA, TopAbs_EDGE);
1453 TopExp_Explorer aFaceExpB (aFaceB, TopAbs_EDGE);
1455 TopoDS_Edge anEdgeA = TopoDS::Edge (aFaceExpA.Current());
1456 TopoDS_Edge anEdgeB = TopoDS::Edge (aFaceExpB.Current());
1458 BRepAdaptor_Curve aCurveA (anEdgeA);
1459 BRepAdaptor_Curve aCurveB (anEdgeB);
1461 gp_Pnt A = aCurveA.Value (0.1);
1462 gp_Pnt B = aCurveA.Value (0.9);
1463 gp_Pnt C = aCurveB.Value (0.5);
1465 GC_MakePlane aMkPlane (A,B,C);
1467 aRelation = new AIS_TangentRelation (aFaceA, aFaceB, aMkPlane.Value());
1472 case AIS_KOR_SYMMETRIC:
1474 if (aShapes.Extent() != 3)
1476 std::cerr << "Error: Wrong number of selected shapes.\n";
1480 TopoDS_Shape aSelectedShapes[3];
1481 Standard_Integer anIdx = 0;
1482 TopTools_ListOfShape::Iterator anIter (aShapes);
1483 for (; anIter.More(); anIter.Next(), ++anIdx)
1485 aSelectedShapes[anIdx] = anIter.Value();
1488 TopoDS_Edge anEdgeA = TopoDS::Edge (aSelectedShapes[0]);
1489 if (aSelectedShapes[1].ShapeType() == TopAbs_EDGE)
1491 // 1 - edge, 2 - edge, 3 - edge.
1492 TopoDS_Edge anEdgeB = TopoDS::Edge (aSelectedShapes[1]);
1493 TopoDS_Edge anEdgeC = TopoDS::Edge (aSelectedShapes[2]);
1495 BRepExtrema_ExtCC aDeltaEdgeAB (anEdgeA, anEdgeB);
1496 BRepExtrema_ExtCC aDeltaEdgeAC (anEdgeA, anEdgeC);
1498 if (!aDeltaEdgeAB.IsParallel())
1500 std::cerr << "Syntax error: the edges are not parallel.\n";
1503 if (!aDeltaEdgeAC.IsParallel())
1505 std::cerr << "Syntax error: the edges are not parallel.\n";
1509 TopoDS_Vertex Va, Vb, Vc, Vd;
1510 TopExp::Vertices (anEdgeB, Va, Vb);
1511 TopExp::Vertices (anEdgeC, Vc, Vd);
1512 gp_Pnt A = BRep_Tool::Pnt (Va);
1513 gp_Pnt B = BRep_Tool::Pnt (Vc);
1514 gp_Pnt C = Get3DPointAtMousePosition();
1516 GC_MakePlane aMkPlane (A, B, C);
1518 aRelation = new AIS_SymmetricRelation (anEdgeA, anEdgeB, anEdgeC, aMkPlane.Value());
1522 // 1 - edge, 2 - vertex, 3 - vertex
1523 TopoDS_Vertex aVertexB = TopoDS::Vertex (aSelectedShapes[1]);
1524 TopoDS_Vertex aVertexC = TopoDS::Vertex (aSelectedShapes[2]);
1526 gp_Pnt B = BRep_Tool::Pnt (aVertexB);
1527 gp_Pnt C = BRep_Tool::Pnt (aVertexC);
1529 TopoDS_Vertex Va, Vb;
1530 TopExp::Vertices (anEdgeA, Va, Vb);
1531 gp_Pnt A = BRep_Tool::Pnt (Va);
1533 GC_MakePlane aMkPlane(A, B, C);
1534 aRelation = new AIS_SymmetricRelation (anEdgeA, aVertexB, aVertexC, aMkPlane.Value());
1542 std::cerr << "Error: Unknown type of relation!\n";
1547 VDisplayAISObject (aName, aRelation);
1551 //=======================================================================
1552 //function : VDimParam
1553 //purpose : Sets aspect parameters to dimension.
1554 //=======================================================================
1555 static int VDimParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
1559 theDi << theArgVec[0] << " error: the wrong number of input parameters.\n";
1564 TCollection_AsciiString aName (theArgVec[1]);
1565 gp_Pln aWorkingPlane;
1566 Standard_Boolean isCustomPlane = Standard_False;
1567 Standard_Boolean toUpdate = Standard_True;
1569 NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
1570 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
1572 Handle(AIS_InteractiveObject) anObject;
1573 if (!GetMapOfAIS().Find2 (aName, anObject))
1575 theDi << theArgVec[0] << "error: no object with this name.\n";
1578 Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (anObject);
1581 theDi << theArgVec[0] << "error: no dimension with this name.\n";
1585 Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
1587 if (ParseDimensionParams (theArgNum, theArgVec, 2, anAspect,
1588 isCustomPlane, aWorkingPlane,
1589 aRealParams, aStringParams))
1596 aDim->SetCustomPlane (aWorkingPlane);
1599 SetDimensionParams (aDim, aRealParams, aStringParams);
1601 if (!aDim->IsValid())
1603 std::cerr << "Error: Dimension geometry or plane is not valid.\n";
1607 // Redisplay a dimension after parameter changing.
1608 if (ViewerTest::GetAISContext()->IsDisplayed (aDim))
1610 ViewerTest::GetAISContext()->Redisplay (aDim, toUpdate);
1616 //=======================================================================
1617 //function : VLengthParam
1618 //purpose : Sets parameters to length dimension.
1619 //=======================================================================
1620 static int VLengthParam (Draw_Interpretor&, Standard_Integer theArgNum, const char** theArgVec)
1624 std::cout << theArgVec[0] << " error: the wrong number of input parameters.\n";
1628 TCollection_AsciiString aName (theArgVec[1]);
1629 Handle(AIS_InteractiveObject) anObject;
1630 if (!GetMapOfAIS().Find2 (aName, anObject))
1632 std::cout << theArgVec[0] << "error: no object with this name.\n";
1636 Handle(AIS_LengthDimension) aLengthDim = Handle(AIS_LengthDimension)::DownCast (anObject);
1637 if (aLengthDim.IsNull())
1639 std::cout << theArgVec[0] << "error: no length dimension with this name.\n";
1643 // parse direction value
1645 int anArgumentIt = 2;
1646 TCollection_AsciiString aParam (theArgVec[anArgumentIt]);
1649 bool isCustomDirection = false;
1650 if (aParam.IsEqual ("-direction"))
1652 if (anArgumentIt + 1 >= theArgNum)
1654 std::cout << "Error: "<< aParam <<" direction should have value.\n";
1658 isCustomDirection = Standard_True;
1659 TCollection_AsciiString aValue = theArgVec[anArgumentIt];
1662 aDirection = gp::DX();
1663 else if (aValue == "oy")
1664 aDirection = gp::DY();
1665 else if (aValue == "oz")
1666 aDirection = gp::DZ();
1667 else if (aValue == "autodirection")
1668 isCustomDirection = false;
1671 if (anArgumentIt + 2 >= theArgNum)
1673 std::cout << "Error: wrong number of values for parameter '" << aParam << "'.\n";
1676 // access coordinate arguments
1677 TColStd_SequenceOfReal aCoords;
1678 for (; anArgumentIt < theArgNum; ++anArgumentIt)
1680 TCollection_AsciiString anArg (theArgVec[anArgumentIt]);
1681 if (!anArg.IsRealValue())
1685 aCoords.Append (anArg.RealValue());
1687 // non-numeric argument too early
1688 if (aCoords.IsEmpty() || aCoords.Size() != 3)
1690 std::cout << "Error: wrong number of direction arguments.\n";
1693 aDirection = gp_Dir (aCoords.Value (1), aCoords.Value (2), aCoords.Value (3));
1697 aLengthDim->SetDirection (aDirection, isCustomDirection);
1698 if (!aLengthDim->IsValid())
1700 std::cout << "Error: Dimension geometry or plane is not valid.\n";
1704 // Redisplay a dimension after parameter changing.
1705 if (ViewerTest::GetAISContext()->IsDisplayed (aLengthDim))
1707 ViewerTest::GetAISContext()->Redisplay (aLengthDim, true);
1713 //=======================================================================
1714 //function : VAngleParam
1715 //purpose : Sets aspect parameters to angle dimension.
1716 //=======================================================================
1717 static int VAngleParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
1721 theDi << theArgVec[0] << " error: the wrong number of input parameters.\n";
1726 TCollection_AsciiString aName (theArgVec[1]);
1727 gp_Pln aWorkingPlane;
1728 Standard_Boolean toUpdate = Standard_True;
1730 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
1731 Handle(AIS_InteractiveObject) anObject;
1732 if (!GetMapOfAIS().Find2 (aName, anObject))
1734 theDi << theArgVec[0] << "error: no object with this name.\n";
1738 Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (anObject);
1741 theDi << theArgVec[0] << "error: no dimension with this name.\n";
1745 Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
1746 if (ParseAngleDimensionParams (theArgNum, theArgVec, 2, aStringParams))
1751 SetAngleDimensionParams (aDim, aStringParams);
1753 if (!aDim->IsValid())
1755 std::cerr << "Error: Dimension geometry or plane is not valid.\n";
1759 // Redisplay a dimension after parameter changing.
1760 if (ViewerTest::GetAISContext()->IsDisplayed (aDim))
1762 ViewerTest::GetAISContext()->Redisplay (aDim, toUpdate);
1767 //=======================================================================
1768 //function : VMoveDim
1769 //purpose : Moves dimension or relation text label to defined or picked
1770 // position and updates the object.
1771 //draw args: vmovedim [name] [x y z]
1772 //=======================================================================
1773 static int VMoveDim (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
1777 theDi << theArgVec[0] << " error: the wrong number of parameters.\n";
1781 // Parameters parsing
1782 Standard_Boolean isNameSet = (theArgNum ==2 || theArgNum == 5);
1783 Standard_Boolean isPointSet = (theArgNum == 4 || theArgNum == 5);
1785 Handle(AIS_InteractiveObject) aPickedObj;
1786 gp_Pnt aPoint (gp::Origin());
1787 Standard_Integer aMaxPickNum = 5;
1792 TCollection_AsciiString aName (theArgVec[1]);
1793 if (!GetMapOfAIS().Find2 (aName, aPickedObj)
1794 || aPickedObj.IsNull())
1796 theDi << theArgVec[0] << " error: no object with this name.\n";
1800 if (aPickedObj->Type() != AIS_KOI_Dimension && aPickedObj->Type() != AIS_KOI_Relation)
1802 theDi << theArgVec[0] << " error: no dimension or relation with this name.\n";
1806 else // Pick dimension or relation
1808 // Loop that will be handle picking.
1809 Standard_Integer anArgNum = 5;
1810 const char *aBuffer[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1811 const char **anArgVec = (const char **) aBuffer;
1813 Standard_Boolean isPicked = Standard_False;
1814 Standard_Integer aPickNum = 0;
1815 while (!isPicked && aPickNum < aMaxPickNum)
1817 while (ViewerMainLoop (anArgNum, anArgVec)) { }
1819 for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
1821 aPickedObj = TheAISContext()->SelectedInteractive();
1824 isPicked = (!aPickedObj.IsNull() && (aPickedObj->Type() == AIS_KOI_Dimension || aPickedObj->Type() == AIS_KOI_Relation));
1834 theDi << theArgVec[0] << ": no dimension or relation is selected.\n";
1842 aPoint = theArgNum == 4 ? gp_Pnt (atoi (theArgVec[1]), atoi (theArgVec[2]), atoi (theArgVec[3]))
1843 : gp_Pnt (atoi (theArgVec[2]), atoi (theArgVec[3]), atoi (theArgVec[4]));
1845 else // Pick the point
1847 Standard_Integer aPickArgNum = 5;
1848 const char *aPickBuff[] = {"VPick", "X", "VPickY", "VPickZ", "VPickShape"};
1849 const char **aPickArgVec = (const char **) aPickBuff;
1851 while (ViewerMainLoop (aPickArgNum, aPickArgVec)) { }
1853 // Set text position, update relation or dimension.
1854 if (aPickedObj->Type() == AIS_KOI_Relation)
1856 Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (aPickedObj);
1857 aPoint = Get3DPointAtMousePosition();
1858 aRelation->SetPosition (aPoint);
1859 TheAISContext()->Redisplay (aRelation, Standard_True);
1863 Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (aPickedObj);
1864 gp_Pnt aFirstPoint, aSecondPoint;
1865 if (aDim->KindOfDimension() == AIS_KOD_PLANEANGLE)
1867 Handle(AIS_AngleDimension) anAngleDim = Handle(AIS_AngleDimension)::DownCast (aDim);
1868 aFirstPoint = anAngleDim->FirstPoint();
1869 aSecondPoint = anAngleDim->SecondPoint();
1871 else if (aDim->KindOfDimension() == AIS_KOD_LENGTH)
1873 Handle(AIS_LengthDimension) aLengthDim = Handle(AIS_LengthDimension)::DownCast (aDim);
1874 aFirstPoint = aLengthDim->FirstPoint();
1875 aSecondPoint = aLengthDim->SecondPoint();
1877 else if (aDim->KindOfDimension() == AIS_KOD_RADIUS)
1879 Handle(AIS_RadiusDimension) aRadiusDim = Handle(AIS_RadiusDimension)::DownCast (aDim);
1880 aFirstPoint = aRadiusDim->AnchorPoint();
1881 aSecondPoint = aRadiusDim->Circle().Location();
1883 else if (aDim->KindOfDimension() == AIS_KOD_DIAMETER)
1885 Handle(AIS_DiameterDimension) aDiameterDim = Handle(AIS_DiameterDimension)::DownCast (aDim);
1886 aFirstPoint = aDiameterDim->AnchorPoint();
1887 aSecondPoint = aDiameterDim->Circle().Location();
1890 if (!Get3DPointAtMousePosition (aFirstPoint, aSecondPoint, aPoint))
1895 aDim->SetTextPosition (aPoint);
1896 TheAISContext()->Redisplay (aDim, Standard_True);
1901 // Set text position, update relation or dimension.
1902 if (aPickedObj->Type() == AIS_KOI_Relation)
1904 Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (aPickedObj);
1905 aRelation->SetPosition (aPoint);
1906 TheAISContext()->Redisplay (aRelation, Standard_True);
1910 Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (aPickedObj);
1911 aDim->SetTextPosition (aPoint);
1912 TheAISContext()->Redisplay (aDim, Standard_True);
1918 //=======================================================================
1919 //function : RelationsCommands
1921 //=======================================================================
1924 void ViewerTest::RelationCommands(Draw_Interpretor& theCommands)
1926 const char *group = "AISRelations";
1928 theCommands.Add("vdimension",
1929 "vdimension name {-angle|-length|-radius|-diameter}"
1930 "[-shapes shape1 [shape2 [shape3]]\n"
1932 "[-text 3d|2d wf|sh|wireframe|shading IntegerSize]\n"
1933 "[-font FontName]\n"
1934 "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
1935 "[-arrow external|internal|fit]\n"
1936 "[{-arrowlength|-arlen} RealArrowLength]\n"
1937 "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
1938 "[-plane xoy|yoz|zox]\n"
1939 "[-flyout FloatValue -extension FloatValue]\n"
1941 "[-value CustomRealValue]\n"
1942 "[-textvalue CustomTextValue]\n"
1943 "[-dispunits DisplayUnitsString]\n"
1944 "[-modelunits ModelUnitsString]\n"
1945 "[-showunits | -hideunits]\n"
1946 " -Builds angle, length, radius and diameter dimensions.\n"
1947 " -See also: vdimparam, vmovedim.\n",
1948 __FILE__,VDimBuilder,group);
1950 theCommands.Add ("vrelation",
1951 "vrelation name {-concentric|-equaldistance|-equalradius|-fix|-identic|-offset|-parallel|-perpendicular|-tangent|-symmetric}"
1952 "\n\t\t: concentric - 2 circled edges."
1953 "\n\t\t: equaldistance - 4 vertex/edges."
1954 "\n\t\t: equalradius - 1 or 2 circled edges."
1955 "\n\t\t: fix - 1 edge."
1956 "\n\t\t: identic - 2 faces, edges or vertices."
1957 "\n\t\t: offset - 2 faces."
1958 "\n\t\t: parallel - 2 faces or 2 edges."
1959 "\n\t\t: perpendicular - 2 faces or 2 edges."
1960 "\n\t\t: tangent - two coplanar edges (first the circular edge then the tangent edge) or two faces."
1961 "\n\t\t: symmetric - 3 edges or 1 edge and 2 vertices."
1962 "-Builds specific relation from selected objects.",
1963 __FILE__, VRelationBuilder, group);
1965 theCommands.Add("vdimparam",
1967 "[-text 3d|2d wf|sh|wireframe|shading IntegerSize]\n"
1968 "[-font FontName]\n"
1969 "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
1970 "[-arrow external|internal|fit]\n"
1971 "[{-arrowlength|-arlen} RealArrowLength]\n"
1972 "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
1973 "[-plane xoy|yoz|zox]\n"
1974 "[-flyout FloatValue -extension FloatValue]\n"
1975 "[-value CustomNumberValue]\n"
1976 "[-textvalue CustomTextValue]\n"
1977 "[-dispunits DisplayUnitsString]\n"
1978 "[-modelunits ModelUnitsString]\n"
1979 "[-showunits | -hideunits]\n"
1980 " -Sets parameters for angle, length, radius and diameter dimensions.\n"
1981 " -See also: vmovedim, vdimension.\n",
1982 __FILE__,VDimParam,group);
1984 theCommands.Add("vlengthparam",
1986 "[-direction {ox|oy|oz|x y z|autodirection}]\n"
1987 " -Sets parameters for length dimension.\n"
1988 " -See also: vdimparam, vdimension.\n",
1989 __FILE__,VLengthParam,group);
1991 theCommands.Add("vangleparam",
1993 "[-type interior|exterior]\n"
1994 "[-showarrow first|second|both|none]\n"
1995 " -Sets parameters for angle dimension.\n"
1996 " -See also: vdimparam, vdimension.\n",
1997 __FILE__,VAngleParam,group);
1999 theCommands.Add("vmovedim",
2000 "vmovedim : vmovedim [name] [x y z]"
2001 "\n\t\t: Moves picked or named (if name defined)"
2002 "\n\t\t: dimension to picked mouse position or input point."
2003 "\n\t\t: Text label of dimension 'name' is moved to position, another parts of dimensionare adjusted.",
2004 __FILE__,VMoveDim,group);