0028895: Visualization, V3d_View::SetComputedMode() - HLR calculation is performed...
[occt.git] / src / ViewerTest / ViewerTest_RelationCommands.cxx
CommitLineData
b311480e 1// Created on: 1998-11-12
2// Created by: Robert COUBLANC
3// Copyright (c) 1998-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 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
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#include <ViewerTest.hxx>
7fd59977 18
a6eb515f 19#include <AIS_AngleDimension.hxx>
20#include <AIS_Circle.hxx>
1c078d3b 21#include <AIS_ConcentricRelation.hxx>
a6eb515f 22#include <AIS_DiameterDimension.hxx>
23#include <AIS_DisplayMode.hxx>
1c078d3b 24#include <AIS_EqualDistanceRelation.hxx>
25#include <AIS_EqualRadiusRelation.hxx>
26#include <AIS_FixRelation.hxx>
27#include <AIS_IdenticRelation.hxx>
7fd59977 28#include <AIS_InteractiveContext.hxx>
404c8936 29#include <AIS_KindOfRelation.hxx>
a6eb515f 30#include <AIS_LengthDimension.hxx>
31#include <AIS_ListIteratorOfListOfInteractive.hxx>
32#include <AIS_ListOfInteractive.hxx>
33#include <AIS_MapOfInteractive.hxx>
1c078d3b 34#include <AIS_OffsetDimension.hxx>
35#include <AIS_ParallelRelation.hxx>
36#include <AIS_PerpendicularRelation.hxx>
a6eb515f 37#include <AIS_Point.hxx>
38#include <AIS_RadiusDimension.hxx>
39#include <AIS_Relation.hxx>
40#include <AIS_Shape.hxx>
1c078d3b 41#include <AIS_SymmetricRelation.hxx>
42#include <AIS_TangentRelation.hxx>
a6eb515f 43#include <BRep_Builder.hxx>
44#include <BRep_Tool.hxx>
1c078d3b 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>
a6eb515f 52#include <BRepTools.hxx>
7fd59977 53#include <Draw_Interpretor.hxx>
54#include <Draw.hxx>
55#include <Draw_Appli.hxx>
a6eb515f 56#include <Draw_Window.hxx>
7fd59977 57#include <DBRep.hxx>
a6eb515f 58#include <ElSLib.hxx>
6fb1a930 59#include <Font_FontMgr.hxx>
a6eb515f 60#include <GC_MakePlane.hxx>
61#include <Geom_CartesianPoint.hxx>
62#include <Geom_Circle.hxx>
af203d54 63#include <Geom_Line.hxx>
a6eb515f 64#include <Geom_Plane.hxx>
af203d54 65#include <GeomAPI_IntCS.hxx>
66#include <gce_MakeLin.hxx>
67#include <gce_MakePln.hxx>
a6eb515f 68#include <gp_Circ.hxx>
69#include <gp_Pln.hxx>
70#include <IntAna_IntConicQuad.hxx>
71#include <IntAna_Quadric.hxx>
72#include <Precision.hxx>
a6eb515f 73#include <StdSelect.hxx>
7fd59977 74#include <TCollection_AsciiString.hxx>
a6eb515f 75#include <TCollection_ExtendedString.hxx>
76#include <TColStd_MapOfInteger.hxx>
77#include <TopAbs.hxx>
78#include <TopAbs_ShapeEnum.hxx>
79#include <TopExp.hxx>
1c078d3b 80#include <TopExp_Explorer.hxx>
a6eb515f 81#include <TopoDS.hxx>
82#include <TopoDS_Face.hxx>
83#include <TopoDS_Solid.hxx>
84#include <TopoDS_Vertex.hxx>
7fd59977 85#include <V3d_Viewer.hxx>
86#include <V3d_View.hxx>
87#include <V3d.hxx>
7fd59977 88#include <ViewerTest_DoubleMapOfInteractiveAndName.hxx>
89#include <ViewerTest_DoubleMapIteratorOfDoubleMapOfInteractiveAndName.hxx>
90#include <ViewerTest_EventManager.hxx>
92efcf78 91#include <AIS_InteractiveObject.hxx>
92#include <AIS_Dimension.hxx>
7fd59977 93
af203d54 94extern Standard_Boolean VDisplayAISObject (const TCollection_AsciiString& theName,
95 const Handle(AIS_InteractiveObject)& theAISObj,
96 Standard_Boolean theReplaceIfExists = Standard_True);
7fd59977 97extern ViewerTest_DoubleMapOfInteractiveAndName& GetMapOfAIS();
98extern int ViewerMainLoop(Standard_Integer argc, const char** argv);
99extern Handle(AIS_InteractiveContext)& TheAISContext ();
100
7fd59977 101#define VertexMask 0x01
102#define EdgeMask 0x02
103#define FaceMask 0x04
104
7fd59977 105//=======================================================================
106//function : Get3DPointAtMousePosition
af203d54 107//purpose : Calculates the 3D points corresponding to the mouse position
108// in the plane of the view
7fd59977 109//=======================================================================
af203d54 110static gp_Pnt Get3DPointAtMousePosition()
a6eb515f 111{
af203d54 112 Handle(V3d_View) aView = ViewerTest::CurrentView();
af203d54 113
7fd59977 114 Standard_Real xv,yv,zv;
af203d54 115 aView->Proj (xv,yv,zv);
7fd59977 116 Standard_Real xat,yat,zat;
af203d54 117 aView->At(xat,yat,zat);
118 gp_Pln aPlane (gp_Pnt(xat,yat,zat), gp_Dir(xv,yv,zv));
119
120 Standard_Integer aPixX, aPixY;
121 Standard_Real aX, aY, aZ, aDX, aDY, aDZ;
122
123 ViewerTest::GetMousePosition (aPixX, aPixY);
124 aView->ConvertWithProj (aPixX, aPixY, aX, aY, aZ, aDX, aDY, aDZ);
125 gp_Lin aLine( gp_Pnt(aX, aY, aZ), gp_Dir(aDX, aDY, aDZ) );
126
127 // Compute intersection
128 Handle(Geom_Line) aGeomLine = new Geom_Line (aLine);
129 Handle(Geom_Plane) aGeomPlane = new Geom_Plane (aPlane);
130 GeomAPI_IntCS anIntersector (aGeomLine, aGeomPlane);
131 if (!anIntersector.IsDone() || anIntersector.NbPoints() == 0)
132 {
133 return gp::Origin();
134 }
135 return anIntersector.Point (1);
7fd59977 136}
137
7fd59977 138//=======================================================================
af203d54 139//function : Get3DPointAtMousePosition
140//purpose : Calculates the 3D points corresponding to the mouse position
141// in the plane of the view
7fd59977 142//=======================================================================
af203d54 143static Standard_Boolean Get3DPointAtMousePosition (const gp_Pnt& theFirstPoint,
144 const gp_Pnt& theSecondPoint,
145 gp_Pnt& theOutputPoint)
7fd59977 146{
af203d54 147 theOutputPoint = gp::Origin();
148
149 Handle(V3d_View) aView = ViewerTest::CurrentView();
150
151 Standard_Integer aPixX, aPixY;
152 Standard_Real aX, aY, aZ, aDx, aDy, aDz, aUx, aUy, aUz;
153
154 // Get 3D point in view coordinates and projection vector from the pixel point.
155 ViewerTest::GetMousePosition (aPixX, aPixY);
156 aView->ConvertWithProj (aPixX, aPixY, aX, aY, aZ, aDx, aDy, aDz);
157 gp_Lin aProjLin (gp_Pnt(aX, aY, aZ), gp_Dir(aDx, aDy, aDz));
158
159 // Get plane
160 gp_Vec aDimVec (theFirstPoint, theSecondPoint);
161 aView->Up (aUx, aUy, aUz);
162 gp_Vec aViewUp (aUx, aUy, aUz);
163
164 if (aDimVec.IsParallel (aViewUp, Precision::Angular()))
165 {
166 theOutputPoint = Get3DPointAtMousePosition();
167 return Standard_True;
7fd59977 168 }
af203d54 169
170 gp_Vec aDimNormal = aDimVec ^ aViewUp;
171 gp_Pln aViewPlane= gce_MakePln (theFirstPoint, aDimNormal);
172
173 // Get intersection of view plane and projection line
174 Handle(Geom_Plane) aPlane = new Geom_Plane (aViewPlane);
175 Handle(Geom_Line) aProjLine = new Geom_Line (aProjLin);
176 GeomAPI_IntCS anIntersector (aProjLine, aPlane);
177 if (!anIntersector.IsDone() || anIntersector.NbPoints() == 0)
178 {
179 return Standard_False;
7fd59977 180 }
af203d54 181
182 theOutputPoint = anIntersector.Point (1);
183 return Standard_True;
7fd59977 184}
185
a6eb515f 186//=======================================================================
0499eb06 187//function : ParseDimensionParams
188//purpose : Auxilliary function: sets aspect parameters for
189// length, angle, radius and diameter dimension.
190//
191//draw args: -text [3d|2d] [wf|sh|wireframe|shading] [Size]
192// -label [left|right|hcenter|hfit] [top|bottom|vcenter|vfit]
193// -arrow [external|internal|fit] [Length(int)]
194// -arrowangle ArrowAngle(degrees)
195// -plane xoy|yoz|zox
196// -flyout FloatValue -extension FloatValue
73ddbb9a 197// -autovalue
198// -value CustomRealValue
199// -textvalue CustomTextValue
1c9d1517 200// -dispunits DisplayUnitsString
201// -modelunits ModelUnitsString
202// -showunits
203// -hideunits
0499eb06 204//
205// Warning! flyout is not an aspect value, it is for dimension parameter
1c9d1517 206// likewise text position, but text position override other paramaters.
207// For text position changing use 'vmovedim'.
a6eb515f 208//=======================================================================
0499eb06 209static int ParseDimensionParams (Standard_Integer theArgNum,
210 const char** theArgVec,
211 Standard_Integer theStartIndex,
212 const Handle(Prs3d_DimensionAspect)& theAspect,
1c9d1517 213 Standard_Boolean& theIsCustomPlane, gp_Pln& thePlane,
214 NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
215 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams,
0499eb06 216 NCollection_List<Handle(AIS_InteractiveObject)>* theShapeList = NULL)
a6eb515f 217{
1c9d1517 218 theRealParams.Clear();
219 theStringParams.Clear();
220
0499eb06 221 theIsCustomPlane = Standard_False;
a6eb515f 222
1c9d1517 223 // Begin from the second parameter: the first one is dimension name
0499eb06 224 for (Standard_Integer anIt = theStartIndex; anIt < theArgNum; ++anIt)
a6eb515f 225 {
0499eb06 226 TCollection_AsciiString aParam (theArgVec[anIt]);
227 aParam.LowerCase();
1d7ca641 228
0499eb06 229 if (aParam.Search ("-") == -1)
a6eb515f 230 {
0499eb06 231 continue;
232 }
1d7ca641 233
1c9d1517 234 // Boolean flags
73ddbb9a 235 if (aParam.IsEqual ("-autovalue"))
236 {
237 theRealParams.Bind ("autovalue", 1);
238 continue;
239 }
240
1c9d1517 241 if (aParam.IsEqual ("-showunits"))
242 {
243 theAspect->MakeUnitsDisplayed (Standard_True);
244 continue;
245 }
246 else if (aParam.IsEqual ("-hideunits"))
247 {
248 theAspect->MakeUnitsDisplayed (Standard_False);
249 continue;
250 }
404c8936 251 else if (aParam.IsEqual ("-selected"))
252 {
253 if (!theShapeList)
254 {
255 std::cerr << "Error: unknown parameter '" << aParam << "'\n";
256 return 1;
257 }
258
259 for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
260 {
261 TopoDS_Shape aShape = TheAISContext()->SelectedShape();
262 if (!aShape.IsNull())
263 {
264 theShapeList->Append (new AIS_Shape (aShape));
265 }
266 }
267 continue;
268 }
1c9d1517 269
0499eb06 270 // Before all non-boolean flags parsing check if a flag have at least one value.
271 if (anIt + 1 >= theArgNum)
272 {
273 std::cerr << "Error: "<< aParam <<" flag should have value.\n";
274 return 1;
275 }
276
277 // Non-boolean flags
278 if (aParam.IsEqual ("-shape")
279 || aParam.IsEqual ("-shapes"))
280 {
281 if (!theShapeList)
a6eb515f 282 {
0499eb06 283 std::cerr << "Error: unknown parameter '" << aParam << "'\n";
284 return 1;
1d7ca641 285 }
1d7ca641 286
0499eb06 287 do
1d7ca641 288 {
0499eb06 289 anIt++;
290 TCollection_AsciiString anArgString = theArgVec[anIt];
291 Handle(AIS_InteractiveObject) anAISObject;
292 Standard_CString aStr = anArgString.ToCString();
293 TopoDS_Shape aShape = DBRep::Get (aStr);
294 if (!aShape.IsNull())
1d7ca641 295 {
0499eb06 296 anAISObject = new AIS_Shape (aShape);
1d7ca641 297 }
298 else
299 {
0499eb06 300 if (!GetMapOfAIS().IsBound2 (anArgString))
1d7ca641 301 {
0499eb06 302 std::cerr << "Error: shape with name '" << aStr << "' is not found.\n";
303 return 1;
1d7ca641 304 }
305
0499eb06 306 anAISObject = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (anArgString));
307 if (anAISObject.IsNull())
1d7ca641 308 {
0499eb06 309 std::cerr << "Error: " << aStr <<" is not a shape.\n";
1d7ca641 310 return 1;
311 }
312 }
0499eb06 313 theShapeList->Append (anAISObject);
1d7ca641 314 }
0499eb06 315 while (anIt + 1 < theArgNum && theArgVec[anIt + 1][0] != '-');
316 }
317 else if (aParam.IsEqual ("-text"))
318 {
319 do
1d7ca641 320 {
0499eb06 321 anIt++;
322 TCollection_AsciiString aValue (theArgVec[anIt]);
323 aValue.LowerCase();
324 if (aValue.IsEqual ("3d"))
1d7ca641 325 {
0499eb06 326 theAspect->MakeText3d (Standard_True);
1d7ca641 327 }
0499eb06 328 else if (aValue.IsEqual ("2d"))
329 {
330 theAspect->MakeText3d (Standard_False);
331 }
332 else if (aValue.IsEqual ("wf") || aValue.IsEqual ("wireframe"))
333 {
334 theAspect->MakeTextShaded (Standard_False);
335 }
336 else if ( aValue.IsEqual ("sh") || aValue.IsEqual ("shading"))
1d7ca641 337 {
0499eb06 338 theAspect->MakeTextShaded (Standard_True);
1d7ca641 339 }
0499eb06 340 else if (aValue.IsIntegerValue()) // text size
1d7ca641 341 {
0499eb06 342 theAspect->TextAspect()->SetHeight (Draw::Atoi (aValue.ToCString()));
1d7ca641 343 }
0499eb06 344 }
345 while (anIt + 1 < theArgNum && theArgVec[anIt + 1][0] != '-');
346 }
6fb1a930 347 else if (aParam.IsEqual ("-font"))
348 {
349 if (anIt + 1 >= theArgNum)
350 {
351 std::cout << "Error: wrong number of values for parameter '" << aParam.ToCString() << "'.\n";
352 return 1;
353 }
354
355 theAspect->TextAspect()->SetFont (theArgVec[++anIt]);
356 }
0499eb06 357 else if (aParam.IsEqual ("-label"))
358 {
359 do
360 {
361 anIt++;
362 TCollection_AsciiString aParamValue (theArgVec[anIt]);
363 aParamValue.LowerCase();
364
365 if (aParamValue == "left") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Left); }
366 else if (aParamValue == "right") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Right); }
367 else if (aParamValue == "hcenter") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Center);}
368 else if (aParamValue == "hfit") { theAspect->SetTextHorizontalPosition (Prs3d_DTHP_Fit); }
369 else if (aParamValue == "above") { theAspect->SetTextVerticalPosition (Prs3d_DTVP_Above); }
370 else if (aParamValue == "below") { theAspect->SetTextVerticalPosition (Prs3d_DTVP_Below); }
371 else if (aParamValue == "vcenter") { theAspect->SetTextVerticalPosition (Prs3d_DTVP_Center);}
372 else
1d7ca641 373 {
0499eb06 374 std::cerr << "Error: invalid label position: '" << aParamValue << "'.\n";
375 return 1;
1d7ca641 376 }
a6eb515f 377 }
0499eb06 378 while (anIt + 1 < theArgNum && theArgVec[anIt+1][0] != '-');
379 }
380 else if (aParam.IsEqual ("-arrow"))
381 {
51740958 382 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
383 aLocalParam.LowerCase();
0499eb06 384
51740958 385 if (aLocalParam == "external") { theAspect->SetArrowOrientation (Prs3d_DAO_External); }
386 if (aLocalParam == "internal") { theAspect->SetArrowOrientation (Prs3d_DAO_Internal); }
387 if (aLocalParam == "fit") { theAspect->SetArrowOrientation (Prs3d_DAO_Fit); }
7a733b19 388 }
389 else if (aParam.IsEqual ("-arrowlength") || aParam.IsEqual ("-arlen"))
390 {
391 TCollection_AsciiString aValue (theArgVec[++anIt]);
392 if (!aValue.IsRealValue())
393 {
394 std::cerr << "Error: arrow lenght should be float degree value.\n";
395 return 1;
0499eb06 396 }
7a733b19 397 theAspect->ArrowAspect()->SetLength (Draw::Atof (aValue.ToCString()));
0499eb06 398 }
7a733b19 399 else if (aParam.IsEqual ("-arrowangle") || aParam.IsEqual ("-arangle"))
0499eb06 400 {
401 TCollection_AsciiString aValue (theArgVec[++anIt]);
402 if (!aValue.IsRealValue())
403 {
404 std::cerr << "Error: arrow angle should be float degree value.\n";
405 return 1;
406 }
407 theAspect->ArrowAspect()->SetAngle (Draw::Atof (aValue.ToCString()));
408 }
1c9d1517 409 else if (aParam.IsEqual ("-color"))
410 {
411 theAspect->SetCommonColor (Quantity_Color (ViewerTest::GetColorFromName (theArgVec[++anIt])));
412 }
413 else if (aParam.IsEqual ("-extension"))
414 {
51740958 415 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
416 if (!aLocalParam.IsRealValue())
1c9d1517 417 {
418 std::cerr << "Error: extension size for dimension should be real value.\n";
419 return 1;
420 }
51740958 421 theAspect->SetExtensionSize (Draw::Atof (aLocalParam.ToCString()));
1c9d1517 422 }
0499eb06 423 else if (aParam.IsEqual ("-plane"))
424 {
425 TCollection_AsciiString aValue (theArgVec[++anIt]);
426 aValue.LowerCase();
427 if (aValue == "xoy")
428 {
429 theIsCustomPlane = Standard_True;
430 thePlane = gp_Pln (gp_Ax3 (gp::XOY()));
431 }
432 else if (aValue == "zox")
433 {
434 theIsCustomPlane = Standard_True;
435 thePlane = gp_Pln (gp_Ax3 (gp::ZOX()));
436 }
437 else if (aValue == "yoz")
438 {
439 theIsCustomPlane = Standard_True;
440 thePlane = gp_Pln (gp_Ax3 (gp::YOZ()));
441 }
a6eb515f 442 else
443 {
0499eb06 444 std::cerr << "Error: wrong plane '" << aValue << "'.\n";
a6eb515f 445 return 1;
446 }
447 }
0499eb06 448 else if (aParam.IsEqual ("-flyout"))
a6eb515f 449 {
51740958 450 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
451 if (!aLocalParam.IsRealValue())
a6eb515f 452 {
0499eb06 453 std::cerr << "Error: flyout for dimension should be real value.\n";
a6eb515f 454 return 1;
455 }
1d7ca641 456
51740958 457 theRealParams.Bind ("flyout", Draw::Atof (aLocalParam.ToCString()));
0499eb06 458 }
1c9d1517 459 else if (aParam.IsEqual ("-value"))
0499eb06 460 {
51740958 461 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
462 if (!aLocalParam.IsRealValue())
1d7ca641 463 {
1c9d1517 464 std::cerr << "Error: dimension value for dimension should be real value.\n";
a6eb515f 465 return 1;
1d7ca641 466 }
1c9d1517 467
51740958 468 theRealParams.Bind ("value", Draw::Atof (aLocalParam.ToCString()));
1c9d1517 469 }
73ddbb9a 470 else if (aParam.IsEqual ("-textvalue"))
471 {
472 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
473
474 theStringParams.Bind ("textvalue", aLocalParam);
475 }
1c9d1517 476 else if (aParam.IsEqual ("-modelunits"))
477 {
51740958 478 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
1c9d1517 479
51740958 480 theStringParams.Bind ("modelunits", aLocalParam);
1c9d1517 481 }
482 else if (aParam.IsEqual ("-dispunits"))
483 {
51740958 484 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
1c9d1517 485
51740958 486 theStringParams.Bind ("dispunits", aLocalParam);
0499eb06 487 }
488 else
489 {
490 std::cerr << "Error: unknown parameter '" << aParam << "'.\n";
491 return 1;
a6eb515f 492 }
493 }
494
0499eb06 495 return 0;
496}
497
1c9d1517 498//=======================================================================
499//function : SetDimensionParams
500//purpose : Sets parameters for dimension
501//=======================================================================
502static void SetDimensionParams (const Handle(AIS_Dimension)& theDim,
503 const NCollection_DataMap<TCollection_AsciiString, Standard_Real>& theRealParams,
504 const NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams)
505{
506 if (theRealParams.IsBound ("flyout"))
507 {
508 theDim->SetFlyout (theRealParams.Find ("flyout"));
509 }
510
73ddbb9a 511 if (theRealParams.IsBound ("autovalue"))
512 {
513 theDim->SetComputedValue();
514 }
515
1c9d1517 516 if (theRealParams.IsBound ("value"))
517 {
518 theDim->SetCustomValue (theRealParams.Find ("value"));
519 }
520
73ddbb9a 521 if (theStringParams.IsBound ("textvalue"))
522 {
523 theDim->SetCustomValue (theStringParams.Find ("textvalue"));
524 }
525
1c9d1517 526 if (theStringParams.IsBound ("modelunits"))
527 {
528 theDim->SetModelUnits (theStringParams.Find ("modelunits"));
529 }
530
531 if (theStringParams.IsBound ("dispunits"))
532 {
533 theDim->SetDisplayUnits (theStringParams.Find ("dispunits"));
534 }
535}
536
ee905e84 537//=======================================================================
538//function : ParseAngleDimensionParams
539//purpose : Auxilliary function: sets custom parameters for angle dimension.
540//
541//draw args: -type [interior|exterior]
542// -showarrow [first|second|both|none]
543//=======================================================================
544static int ParseAngleDimensionParams (Standard_Integer theArgNum,
545 const char** theArgVec,
546 Standard_Integer theStartIndex,
547 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString>& theStringParams)
548{
549 theStringParams.Clear();
550
551 // Begin from the second parameter: the first one is dimension name
552 for (Standard_Integer anIt = theStartIndex; anIt < theArgNum; ++anIt)
553 {
554 TCollection_AsciiString aParam (theArgVec[anIt]);
555 aParam.LowerCase();
556
557 if (aParam.Search ("-") == -1)
558 {
559 std::cerr << "Error: wrong parameter '" << aParam << "'.\n";
560 return 1;
561 }
562
563 // Before all non-boolean flags parsing check if a flag have at least one value.
564 if (anIt + 1 >= theArgNum)
565 {
566 std::cerr << "Error: "<< aParam <<" flag should have value.\n";
567 return 1;
568 }
569
570 if (aParam.IsEqual ("-type"))
571 {
572 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
573
574 theStringParams.Bind ("type", aLocalParam);
575 }
576 else if (aParam.IsEqual ("-showarrow"))
577 {
578 TCollection_AsciiString aLocalParam(theArgVec[++anIt]);
579
580 theStringParams.Bind ("showarrow", aLocalParam);
581 }
582 else
583 {
584 std::cerr << "Error: unknown parameter '" << aParam << "'.\n";
585 return 1;
586 }
587 }
588
589 return 0;
590}
591
592//=======================================================================
593//function : SetAngleDimensionParams
594//purpose : Sets parameters for angle dimension
595//=======================================================================
596static void SetAngleDimensionParams (const Handle(AIS_Dimension)& theDim,
597 const NCollection_DataMap<TCollection_AsciiString,
598 TCollection_AsciiString>& theStringParams)
599{
600 Handle(AIS_AngleDimension) anAngleDim = Handle(AIS_AngleDimension)::DownCast (theDim);
601 if (anAngleDim.IsNull())
602 {
603 return;
604 }
605
606 if (theStringParams.IsBound ("type"))
607 {
608 AIS_TypeOfAngle anAngleType = AIS_TOA_Interior;
609 TCollection_AsciiString anAngleTypeStr = theStringParams.Find ("type");
610 if (anAngleTypeStr.IsEqual("interior"))
611 {
612 anAngleType = AIS_TOA_Interior;
613 }
614 else if (anAngleTypeStr.IsEqual("exterior"))
615 {
616 anAngleType = AIS_TOA_Exterior;
617 }
618 else
619 {
620 std::cerr << "Error: wrong angle type.\n";
621 }
622 anAngleDim->SetType(anAngleType);
623 }
624
625 if (theStringParams.IsBound ("showarrow"))
626 {
627 AIS_TypeOfAngleArrowVisibility anArrowType = AIS_TOAV_Both;
628 TCollection_AsciiString anArrowTypeStr = theStringParams.Find ("showarrow");
629 if (anArrowTypeStr.IsEqual("both"))
630 {
631 anArrowType = AIS_TOAV_Both;
632 }
633 else if (anArrowTypeStr.IsEqual("first"))
634 {
635 anArrowType = AIS_TOAV_First;
636 }
637 else if (anArrowTypeStr.IsEqual("second"))
638 {
639 anArrowType = AIS_TOAV_Second;
640 }
641 else if (anArrowTypeStr.IsEqual("none"))
642 {
643 anArrowType = AIS_TOAV_None;
644 }
645 else
646 {
647 std::cerr << "Error: wrong showarrow type.\n";
648 }
649 anAngleDim->SetArrowsVisibility(anArrowType);
650 }
651}
652
0499eb06 653//=======================================================================
654//function : VDimBuilder
655//purpose : Command for building dimension presentations: angle,
656// length, radius, diameter
657//=======================================================================
658static int VDimBuilder (Draw_Interpretor& /*theDi*/,
659 Standard_Integer theArgsNb,
660 const char** theArgs)
661{
662 if (theArgsNb < 2)
663 {
664 std::cerr << "Error: wrong number of arguments.\n";
665 return 1;
666 }
667
668 // Parse parameters
669 TCollection_AsciiString aName (theArgs[1]);
670
671 NCollection_List<Handle(AIS_InteractiveObject)> aShapes;
672 Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect;
673 Standard_Boolean isPlaneCustom = Standard_False;
674 gp_Pln aWorkingPlane;
1c9d1517 675
676 NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
677 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
0499eb06 678
679 TCollection_AsciiString aDimType(theArgs[2]);
680 aDimType.LowerCase();
681 AIS_KindOfDimension aKindOfDimension;
682 if (aDimType == "-length")
683 {
684 aKindOfDimension = AIS_KOD_LENGTH;
685 }
686 else if (aDimType == "-angle")
687 {
688 aKindOfDimension = AIS_KOD_PLANEANGLE;
689 }
690 else if (aDimType == "-radius")
691 {
692 aKindOfDimension = AIS_KOD_RADIUS;
693 }
694 else if (aDimType == "-diameter" || aDimType == "-diam")
695 {
696 aKindOfDimension = AIS_KOD_DIAMETER;
697 }
698 else
1d7ca641 699 {
0499eb06 700 std::cerr << "Error: wrong type of dimension.\n";
1d7ca641 701 return 1;
702 }
703
0499eb06 704
1c9d1517 705 if (ParseDimensionParams (theArgsNb, theArgs, 3,
706 anAspect,isPlaneCustom,aWorkingPlane,
707 aRealParams, aStringParams, &aShapes))
708 {
709 return 1;
710 }
0499eb06 711
a6eb515f 712 // Build dimension
713 Handle(AIS_Dimension) aDim;
714 switch (aKindOfDimension)
715 {
1d7ca641 716 case AIS_KOD_LENGTH:
a6eb515f 717 {
a6eb515f 718 if (aShapes.Extent() == 1)
719 {
720 if (aShapes.First()->Type() == AIS_KOI_Shape
0499eb06 721 && (Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape().ShapeType() != TopAbs_EDGE)
a6eb515f 722 {
1d7ca641 723 std::cerr << theArgs[0] << ": wrong shape type.\n";
a6eb515f 724 return 1;
725 }
1c078d3b 726 if (!isPlaneCustom)
727 {
728 std::cerr << theArgs[0] << ": can not build dimension without working plane.\n";
729 return 1;
730 }
731
0499eb06 732 // Adjust working plane
733 TopoDS_Edge anEdge = TopoDS::Edge ((Handle(AIS_Shape)::DownCast(aShapes.First()))->Shape());
734 TopoDS_Vertex aFirst, aSecond;
735 TopExp::Vertices (anEdge, aFirst, aSecond);
0499eb06 736 aDim = new AIS_LengthDimension (anEdge, aWorkingPlane);
7a733b19 737
738 // Move standard plane (XOY, YOZ or ZOX) to the first point to make it working for dimension
739 aWorkingPlane.SetLocation (Handle(AIS_LengthDimension)::DownCast (aDim)->FirstPoint());
a6eb515f 740 }
741 else if (aShapes.Extent() == 2)
742 {
85a975f1 743 TopoDS_Shape aShape1, aShape2;
744
745 // Getting shapes
746 if (aShapes.First()->DynamicType() == STANDARD_TYPE (AIS_Point))
747 {
1c078d3b 748 aShape1 = Handle(AIS_Point)::DownCast (aShapes.First ())->Vertex();
85a975f1 749 }
750 else if (aShapes.First()->Type() == AIS_KOI_Shape)
751 {
752 aShape1 = (Handle(AIS_Shape)::DownCast (aShapes.First()))->Shape();
753 }
754
755 if (aShapes.Last()->DynamicType() == STANDARD_TYPE (AIS_Point))
756 {
1c078d3b 757 aShape2 = Handle(AIS_Point)::DownCast (aShapes.Last ())->Vertex();
85a975f1 758 }
759 else if (aShapes.Last()->Type() == AIS_KOI_Shape)
760 {
761 aShape2 = (Handle(AIS_Shape)::DownCast (aShapes.Last()))->Shape();
762 }
763
764 if (aShape1.IsNull() || aShape2.IsNull())
765 {
766 std::cerr << theArgs[0] << ": wrong shape type.\n";
767 return 1;
768 }
769
1c078d3b 770 // Face-Face case
771 if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_FACE)
772 {
773 aDim = new AIS_LengthDimension (TopoDS::Face (aShape1), TopoDS::Face (aShape2));
774 }
775 else if (aShape1.ShapeType() == TopAbs_FACE && aShape2.ShapeType() == TopAbs_EDGE)
a6eb515f 776 {
1c078d3b 777 aDim = new AIS_LengthDimension (TopoDS::Face (aShape1), TopoDS::Edge (aShape2));
a6eb515f 778 }
1c078d3b 779 else if (aShape1.ShapeType() == TopAbs_EDGE && aShape2.ShapeType() == TopAbs_FACE)
85a975f1 780 {
1c078d3b 781 aDim = new AIS_LengthDimension (TopoDS::Face (aShape2), TopoDS::Edge (aShape1));
85a975f1 782 }
1c078d3b 783 else
784 {
785 if (!isPlaneCustom)
786 {
787 std::cerr << theArgs[0] << ": can not build dimension without working plane.\n";
788 return 1;
789 }
790 // Vertex-Vertex case
791 if (aShape1.ShapeType() == TopAbs_VERTEX)
792 {
793 aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape1)));
794 }
795 else if (aShape2.ShapeType() == TopAbs_VERTEX)
796 {
797 aWorkingPlane.SetLocation (BRep_Tool::Pnt (TopoDS::Vertex (aShape2)));
798 }
85a975f1 799
1c078d3b 800 aDim = new AIS_LengthDimension (aShape1, aShape2, aWorkingPlane);
801 }
a6eb515f 802 }
803 else
804 {
1d7ca641 805 std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
a6eb515f 806 return 1;
807 }
1d7ca641 808
809 break;
a6eb515f 810 }
1d7ca641 811 case AIS_KOD_PLANEANGLE:
a6eb515f 812 {
813 if (aShapes.Extent() == 1 && aShapes.First()->Type()==AIS_KOI_Shape)
814 {
815 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aShapes.First());
816 if (aShape->Shape().ShapeType() == TopAbs_FACE)
817 aDim = new AIS_AngleDimension (TopoDS::Face(aShape->Shape()));
818 }
819 if (aShapes.Extent() == 2)
820 {
821 Handle(AIS_Shape) aShape1 = Handle(AIS_Shape)::DownCast(aShapes.First());
822 Handle(AIS_Shape) aShape2 = Handle(AIS_Shape)::DownCast(aShapes.Last());
823 if (!aShape1.IsNull() && !aShape2.IsNull()
0499eb06 824 && aShape1->Shape().ShapeType() == TopAbs_EDGE
825 && aShape2->Shape().ShapeType() == TopAbs_EDGE)
a6eb515f 826 aDim = new AIS_AngleDimension (TopoDS::Edge(aShape1->Shape()),TopoDS::Edge(aShape2->Shape()));
827 else
828 {
1d7ca641 829 std::cerr << theArgs[0] << ": wrong shapes for angle dimension.\n";
a6eb515f 830 return 1;
831 }
832 }
833 else if (aShapes.Extent() == 3)
834 {
835 gp_Pnt aP1, aP2, aP3;
836 Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
837 if (aPoint.IsNull())
838 return 1;
839 aP1 = aPoint->Component()->Pnt();
840 aShapes.RemoveFirst();
841 aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
842 if (aPoint.IsNull())
843 return 1;
844 aP2 = aPoint->Component()->Pnt();
845 aShapes.RemoveFirst();
846 aPoint = Handle(AIS_Point)::DownCast (aShapes.First());
847 if (aPoint.IsNull())
848 return 1;
849 aP3 = aPoint->Component()->Pnt();
850 aDim = new AIS_AngleDimension (aP1, aP2, aP3);
851 }
852 else
853 {
1d7ca641 854 std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
a6eb515f 855 return 1;
856 }
1d7ca641 857
858 break;
a6eb515f 859 }
1d7ca641 860 case AIS_KOD_RADIUS: // radius of the circle
a6eb515f 861 {
d29b2469 862 gp_Pnt anAnchor;
863 bool hasAnchor = false;
864 for (NCollection_List<Handle(AIS_InteractiveObject)>::Iterator aShapeIter (aShapes); aShapeIter.More(); aShapeIter.Next())
a6eb515f 865 {
d29b2469 866 if (Handle(AIS_Point) aPoint = Handle(AIS_Point)::DownCast(aShapeIter.Value()))
0499eb06 867 {
d29b2469 868 hasAnchor = true;
869 anAnchor = aPoint->Component()->Pnt();
870 aShapes.Remove (aShapeIter);
871 break;
872 }
873 }
874 if (aShapes.Extent() != 1)
875 {
876 std::cout << "Syntax error: wrong number of shapes to build dimension.\n";
877 return 1;
878 }
879
880 if (Handle(AIS_Circle) aShapeCirc = Handle(AIS_Circle)::DownCast(aShapes.First()))
881 {
882 gp_Circ aCircle = aShapeCirc->Circle()->Circ();
883 if (hasAnchor)
884 {
885 aDim = new AIS_RadiusDimension (aCircle, anAnchor);
0499eb06 886 }
887 else
888 {
d29b2469 889 aDim = new AIS_RadiusDimension (aCircle);
0499eb06 890 }
a6eb515f 891 }
d29b2469 892 else if (Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast(aShapes.First()))
893 {
894 Handle(AIS_RadiusDimension) aRadDim = new AIS_RadiusDimension (aShape->Shape());
895 if (hasAnchor)
896 {
897 aRadDim->SetMeasuredGeometry (aShape->Shape(), anAnchor);
898 }
899 aDim = aRadDim;
900 }
a6eb515f 901 else
902 {
d29b2469 903 std::cout << "Error: shape for radius has wrong type.\n";
a6eb515f 904 return 1;
905 }
1d7ca641 906 break;
a6eb515f 907 }
1d7ca641 908 case AIS_KOD_DIAMETER:
a6eb515f 909 {
910 if (aShapes.Extent() == 1)
911 {
0499eb06 912 if (aShapes.First()->DynamicType() == STANDARD_TYPE(AIS_Circle))
913 {
914 Handle(AIS_Circle) aShape = Handle(AIS_Circle)::DownCast (aShapes.First());
915 gp_Circ aCircle = aShape->Circle()->Circ();
916 aDim = new AIS_DiameterDimension (aCircle);
917 }
918 else
919 {
920 Handle(AIS_Shape) aShape = Handle(AIS_Shape)::DownCast (aShapes.First());
921 if (aShape.IsNull())
922 {
923 std::cerr << "Error: shape for radius is of wrong type.\n";
924 return 1;
925 }
926 aDim = new AIS_DiameterDimension (aShape->Shape());
927 }
a6eb515f 928 }
929 else
930 {
1d7ca641 931 std::cerr << theArgs[0] << ": wrong number of shapes to build dimension.\n";
a6eb515f 932 return 1;
933 }
1d7ca641 934
935 break;
a6eb515f 936 }
1d7ca641 937 default:
a6eb515f 938 {
1d7ca641 939 std::cerr << theArgs[0] << ": wrong type of dimension. Type help for more information.\n";
a6eb515f 940 return 1;
941 }
942 }
1d7ca641 943
0499eb06 944 // Check dimension geometry
945 if (!aDim->IsValid())
946 {
947 std::cerr << theArgs[0] << ":dimension geometry is invalid, " << aDimType.ToCString()
7a733b19 948 << " dimension can't be built on input shapes.\n";
0499eb06 949 return 1;
950 }
951
a6eb515f 952 aDim->SetDimensionAspect (anAspect);
1d7ca641 953
1c9d1517 954 SetDimensionParams (aDim, aRealParams, aStringParams);
1d7ca641 955
0499eb06 956 VDisplayAISObject (aName,aDim);
1d7ca641 957
a6eb515f 958 return 0;
959}
7fd59977 960
404c8936 961namespace
7fd59977 962{
404c8936 963 //! If the given shapes are edges then check whether they are parallel else return true.
964 Standard_Boolean IsParallel (const TopoDS_Shape& theShape1,
965 const TopoDS_Shape& theShape2)
af203d54 966 {
404c8936 967 if (theShape1.ShapeType() == TopAbs_EDGE
968 && theShape2.ShapeType() == TopAbs_EDGE)
af203d54 969 {
404c8936 970 BRepExtrema_ExtCC aDelta (TopoDS::Edge (theShape1),
971 TopoDS::Edge (theShape2));
972 return aDelta.IsParallel();
7fd59977 973 }
7fd59977 974
404c8936 975 return Standard_True;
af203d54 976 }
7fd59977 977}
404c8936 978//=======================================================================
979//function : VRelationBuilder
980//purpose : Command for building realation presentation
981//=======================================================================
982static int VRelationBuilder (Draw_Interpretor& /*theDi*/,
983 Standard_Integer theArgsNb,
984 const char** theArgs)
7fd59977 985{
404c8936 986 if (theArgsNb < 2)
af203d54 987 {
404c8936 988 std::cerr << "Error: wrong number of arguments.\n";
af203d54 989 return 1;
990 }
991
404c8936 992 TCollection_AsciiString aName (theArgs[1]);
993 TCollection_AsciiString aType (theArgs[2]);
af203d54 994
404c8936 995 AIS_KindOfRelation aKindOfRelation = AIS_KOR_NONE;
996 if (aType == "-concentric")
af203d54 997 {
404c8936 998 aKindOfRelation = AIS_KOR_CONCENTRIC;
7fd59977 999 }
404c8936 1000 else if (aType == "-equaldistance")
af203d54 1001 {
404c8936 1002 aKindOfRelation = AIS_KOR_EQUALDISTANCE;
7fd59977 1003 }
404c8936 1004 else if (aType == "-equalradius")
af203d54 1005 {
404c8936 1006 aKindOfRelation = AIS_KOR_EQUALRADIUS;
7fd59977 1007 }
404c8936 1008 else if (aType == "-fix")
1009 {
1010 aKindOfRelation = AIS_KOR_FIX;
7fd59977 1011 }
404c8936 1012 else if (aType == "-identic")
1013 {
1014 aKindOfRelation = AIS_KOR_IDENTIC;
7fd59977 1015 }
404c8936 1016 else if (aType == "-offset")
af203d54 1017 {
404c8936 1018 aKindOfRelation = AIS_KOR_OFFSET;
af203d54 1019 }
404c8936 1020 else if (aType == "-parallel")
af203d54 1021 {
404c8936 1022 aKindOfRelation = AIS_KOR_PARALLEL;
7fd59977 1023 }
404c8936 1024 else if (aType == "-perpendicular")
af203d54 1025 {
404c8936 1026 aKindOfRelation = AIS_KOR_PERPENDICULAR;
af203d54 1027 }
404c8936 1028 else if (aType == "-tangent")
af203d54 1029 {
404c8936 1030 aKindOfRelation = AIS_KOR_TANGENT;
7fd59977 1031 }
404c8936 1032 else if (aType == "-symmetric")
af203d54 1033 {
404c8936 1034 aKindOfRelation = AIS_KOR_SYMMETRIC;
af203d54 1035 }
1036
404c8936 1037 TopTools_ListOfShape aShapes;
1038 ViewerTest::GetSelectedShapes (aShapes);
af203d54 1039
404c8936 1040 // Build relation.
1041 Handle(AIS_Relation) aRelation;
1042 switch (aKindOfRelation)
1043 {
1044 case AIS_KOR_CONCENTRIC:
af203d54 1045 {
404c8936 1046 if (aShapes.Extent() != 2)
af203d54 1047 {
404c8936 1048 std::cerr << "Error: Wrong number of selected shapes.\n";
af203d54 1049 return 1;
1050 }
1051
404c8936 1052 const TopoDS_Shape& aShape1 = aShapes.First();
1053 const TopoDS_Shape& aShape2 = aShapes.Last();
af203d54 1054
404c8936 1055 if (!(aShape1.ShapeType() == TopAbs_EDGE
1056 && aShape2.ShapeType() == TopAbs_EDGE))
1057 {
1058 std::cerr << "Syntax error: selected shapes are not edges.\n";
1059 return 1;
1060 }
af203d54 1061
404c8936 1062 BRepAdaptor_Curve aCurve1 (TopoDS::Edge (aShape1));
1063 gp_Circ aCircle1 = aCurve1.Circle();
1064 gp_Pnt aCenter1 = aCircle1.Location();
1065 gp_Pnt B = aCurve1.Value (0.25);
1066 gp_Pnt C = aCurve1.Value (0.75);
1067 GC_MakePlane aMkPlane (aCenter1, B, C);
af203d54 1068
404c8936 1069 aRelation = new AIS_ConcentricRelation (aShape1, aShape2, aMkPlane.Value());
af203d54 1070
404c8936 1071 break;
7fd59977 1072 }
af203d54 1073
404c8936 1074 case AIS_KOR_EQUALDISTANCE:
a6eb515f 1075 {
404c8936 1076 if (aShapes.Extent() != 4)
af203d54 1077 {
404c8936 1078 std::cerr << "Error: Wrong number of selected shapes.\n";
af203d54 1079 return 1;
1080 }
1081
404c8936 1082 TopoDS_Shape aSelectedShapes[4];
a6eb515f 1083
404c8936 1084 Standard_Integer anIdx = 0;
1085 TopTools_ListOfShape::Iterator anIter (aShapes);
1086 for (; anIter.More(); anIter.Next(), ++anIdx)
1087 {
1088 aSelectedShapes[anIdx] = anIter.Value();
1089 }
7fd59977 1090
404c8936 1091 if (!IsParallel (aSelectedShapes[0], aSelectedShapes[1])
1092 || !IsParallel (aSelectedShapes[2], aSelectedShapes[3]))
1093 {
1094 std::cerr << "Syntax error: non parallel edges.\n";
1095 return 1;
1096 }
af203d54 1097
404c8936 1098 gp_Pnt A, B, C;
1099 if (aSelectedShapes[0].ShapeType() == TopAbs_EDGE)
1100 {
1101 TopoDS_Vertex Va, Vb;
1102 TopExp::Vertices (TopoDS::Edge (aSelectedShapes[0]), Va, Vb);
1103 A = BRep_Tool::Pnt (Va);
1104 B = BRep_Tool::Pnt (Vb);
af203d54 1105
404c8936 1106 if (aSelectedShapes[1].ShapeType() == TopAbs_EDGE)
1107 {
1108 TopoDS_Vertex Vc, Vd;
1109 TopExp::Vertices (TopoDS::Edge (aSelectedShapes[1]), Vc, Vd);
1110 C = BRep_Tool::Pnt (Vc);
1111 }
1112 else
1113 {
1114 C = BRep_Tool::Pnt (TopoDS::Vertex (aSelectedShapes[1]));
1115 }
1116 }
1117 else
1118 {
1119 A = BRep_Tool::Pnt (TopoDS::Vertex (aSelectedShapes[0]));
af203d54 1120
404c8936 1121 if (aSelectedShapes[1].ShapeType() == TopAbs_EDGE)
1122 {
1123 TopoDS_Vertex Vb, Vc;
1124 TopExp::Vertices (TopoDS::Edge (aSelectedShapes[1]), Vb, Vc);
1125 B = BRep_Tool::Pnt (Vb);
1126 C = BRep_Tool::Pnt (Vc);
af203d54 1127
404c8936 1128 }
1129 else
1130 {
1131 B = BRep_Tool::Pnt (TopoDS::Vertex (aSelectedShapes[1]));
1132 C.SetX (B.X() + 5.0);
1133 C.SetY (B.Y() + 5.0);
1134 C.SetZ (B.Z() + 5.0);
af203d54 1135
404c8936 1136 }
1137 }
af203d54 1138
404c8936 1139 GC_MakePlane aMkPlane (A, B, C);
1140 aRelation = new AIS_EqualDistanceRelation (aSelectedShapes[0],
1141 aSelectedShapes[1],
1142 aSelectedShapes[2],
1143 aSelectedShapes[3],
1144 aMkPlane.Value());
af203d54 1145
404c8936 1146 break;
af203d54 1147 }
af203d54 1148
404c8936 1149 case AIS_KOR_EQUALRADIUS:
1150 {
1151 if (aShapes.Extent() != 2 && aShapes.Extent() != 1)
1152 {
1153 std::cerr << "Error: Wrong number of selected shapes.\n";
1154 return 1;
1155 }
af203d54 1156
404c8936 1157 const TopoDS_Shape& aShape1 = aShapes.First();
1158 const TopoDS_Shape& aShape2 = (aShapes.Extent() == 2) ? aShapes.Last() : aShape1;
1159 if (!(aShape1.ShapeType() == TopAbs_EDGE
1160 && aShape2.ShapeType() == TopAbs_EDGE))
1161 {
1162 std::cerr << "Syntax error: selected shapes are not edges.\n";
1163 return 1;
1164 }
af203d54 1165
404c8936 1166 TopoDS_Edge anEdge1 = TopoDS::Edge (aShape1);
1167 TopoDS_Edge anEdge2 = TopoDS::Edge (aShape2);
1168 BRepAdaptor_Curve aCurve1 (anEdge1);
1169 gp_Pnt A = aCurve1.Value (0.1);
1170 gp_Pnt B = aCurve1.Value (0.5);
1171 gp_Pnt C = aCurve1.Value (0.9);
1172 GC_MakePlane aMkPlane (A, B, C);
af203d54 1173
404c8936 1174 aRelation = new AIS_EqualRadiusRelation (anEdge1, anEdge2, aMkPlane.Value());
1175 break;
1176 }
af203d54 1177
404c8936 1178 case AIS_KOR_FIX:
1179 {
1180 if (aShapes.Extent() != 1)
1181 {
1182 std::cerr << "Error: Wrong number of selected shapes.\n";
1183 return 1;
1184 }
af203d54 1185
404c8936 1186 const TopoDS_Shape& aShape = aShapes.First();
1187 if (aShape.ShapeType() != TopAbs_EDGE)
1188 {
1189 std::cerr << "Syntax error: selected shapes are not edges.\n";
1190 return 1;
1191 }
af203d54 1192
404c8936 1193 TopoDS_Edge anEdge = TopoDS::Edge (aShape);
1194 BRepAdaptor_Curve aCurve (anEdge);
1195 gp_Pnt A = aCurve.Value(0.1);
1196 gp_Pnt B = aCurve.Value(0.5);
1197 gp_Pnt D = aCurve.Value(0.9);
1198 gp_Pnt C (B.X() + 5.0, B.Y() + 5.0, B.Z() + 5.0);
1199 GC_MakePlane aMkPlane (A, D, C);
af203d54 1200
404c8936 1201 aRelation = new AIS_FixRelation (anEdge, aMkPlane.Value());
1202 break;
7fd59977 1203 }
af203d54 1204
404c8936 1205 case AIS_KOR_IDENTIC:
af203d54 1206 {
404c8936 1207 if (aShapes.Extent() != 2)
af203d54 1208 {
404c8936 1209 std::cerr << "Error: Wrong number of selected shapes.\n";
af203d54 1210 return 1;
1211 }
1212
404c8936 1213 const TopoDS_Shape& aShapeA = aShapes.First();
1214 const TopoDS_Shape& aShapeB = aShapes.Last();
1215
1216 gp_Pnt A,B,C;
1217 if (aShapeA.ShapeType() == TopAbs_EDGE)
1218 {
1219 TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
1220 BRepAdaptor_Curve aCurveA (anEdgeA);
1221
1222 A = aCurveA.Value (0.1);
1223 B = aCurveA.Value (0.9);
1224 C.SetX (B.X() + 5.0);
1225 C.SetY (B.Y() + 5.0);
1226 C.SetZ (B.Z() + 5.0);
1227 }
1228 else if (aShapeA.ShapeType() == TopAbs_VERTEX)
1229 {
1230 if (aShapeB.ShapeType() == TopAbs_EDGE)
1231 {
1232 TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
1233 BRepAdaptor_Curve aCurveB (anEdgeB);
1234
1235 A = aCurveB.Value (0.1);
1236 B = aCurveB.Value (0.9);
1237 C.SetX (B.X() + 5.0);
1238 C.SetY (B.Y() + 5.0);
1239 C.SetZ (B.Z() + 5.0);
1240 }
1241 else if (aShapeB.ShapeType() == TopAbs_FACE)
1242 {
1243 TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
1244 TopExp_Explorer aFaceExp (aFaceB, TopAbs_EDGE);
1245 TopoDS_Edge anEdgeFromB = TopoDS::Edge (aFaceExp.Current());
1246 BRepAdaptor_Curve aCurveB (anEdgeFromB);
1247 A = aCurveB.Value (0.1);
1248 B = aCurveB.Value (0.5);
1249 C = aCurveB.Value (0.9);
1250 }
1251 else
1252 {
1253 A = BRep_Tool::Pnt (TopoDS::Vertex (aShapeA));
1254 B = BRep_Tool::Pnt (TopoDS::Vertex (aShapeB));
1255 C.SetX (B.X() + 5.0);
1256 C.SetY (B.Y() + 5.0);
1257 C.SetZ (B.Z() + 5.0);
1258 }
1259 }
1260 else
1261 {
1262 TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
1263 TopExp_Explorer aFaceExp (aFaceA, TopAbs_EDGE);
1264 TopoDS_Edge anEdgeFromA = TopoDS::Edge (aFaceExp.Current());
1265 BRepAdaptor_Curve aCurveA (anEdgeFromA);
1266 A = aCurveA.Value (0.1);
1267 B = aCurveA.Value (0.5);
1268 C = aCurveA.Value (0.9);
1269 }
1270
1271 GC_MakePlane aMkPlane (A ,B ,C);
1272 aRelation = new AIS_IdenticRelation (aShapeA, aShapeB, aMkPlane.Value());
1273 break;
7fd59977 1274 }
af203d54 1275
404c8936 1276 case AIS_KOR_OFFSET:
af203d54 1277 {
404c8936 1278 if (aShapes.Extent() != 2)
1279 {
1280 std::cerr << "Error: Wrong number of selected shapes.\n";
1281 return 1;
1282 }
af203d54 1283
404c8936 1284 const TopoDS_Shape& aShape1 = aShapes.First();
1285 const TopoDS_Shape& aShape2 = aShapes.Last();
1286 if (!(aShape1.ShapeType() == TopAbs_FACE
1287 && aShape2.ShapeType() == TopAbs_FACE))
1288 {
1289 std::cerr << "Syntax error: selected shapes are not faces.\n";
1290 return 1;
1291 }
af203d54 1292
404c8936 1293 TopoDS_Face aFace1 = TopoDS::Face (aShape1);
1294 TopoDS_Face aFace2 = TopoDS::Face (aShape2);
60bf98ae 1295
404c8936 1296 BRepExtrema_ExtFF aDelta (aFace1, aFace2);
1297 if (!aDelta.IsParallel())
1298 {
1299 std::cerr << "Syntax error: the faces are not parallel.\n";
1300 return 1;
1301 }
7fd59977 1302
404c8936 1303 Standard_Real aDist = Round (sqrt (aDelta.SquareDistance (1)) * 10.0) / 10.0;
1304 TCollection_ExtendedString aMessage (TCollection_ExtendedString ("offset=") + TCollection_ExtendedString (aDist));
af203d54 1305
404c8936 1306 aRelation = new AIS_OffsetDimension (aFace1, aFace2, aDist, aMessage);
af203d54 1307
404c8936 1308 break;
7fd59977 1309 }
af203d54 1310
404c8936 1311 case AIS_KOR_PARALLEL:
1312 {
1313 if (aShapes.Extent() != 2)
af203d54 1314 {
404c8936 1315 std::cerr << "Error: wrong number of selected shapes.\n";
af203d54 1316 return 1;
1317 }
1318
404c8936 1319 const TopoDS_Shape& aShapeA = aShapes.First();
1320 const TopoDS_Shape& aShapeB = aShapes.Last();
1321 if (aShapeA.ShapeType() == TopAbs_EDGE)
1322 {
1323 TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
1324 TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
1325 BRepExtrema_ExtCC aDeltaEdge (anEdgeA, anEdgeB);
af203d54 1326
404c8936 1327 if (!aDeltaEdge.IsParallel())
1328 {
1329 std::cerr << "Error: the edges are not parallel.\n";
1330 return 1;
1331 }
af203d54 1332
404c8936 1333 BRepAdaptor_Curve aCurveA (anEdgeA);
1334 BRepAdaptor_Curve aCurveB (anEdgeB);
7fd59977 1335
404c8936 1336 gp_Pnt A = aCurveA.Value (0.1);
1337 gp_Pnt B = aCurveA.Value (0.9);
1338 gp_Pnt C = aCurveB.Value (0.5);
7fd59977 1339
404c8936 1340 GC_MakePlane aMkPlane (A, B, C);
af203d54 1341
404c8936 1342 aRelation = new AIS_ParallelRelation (anEdgeA, anEdgeB, aMkPlane.Value());
1343 }
1344 else
1345 {
1346 TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
1347 TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
af203d54 1348
404c8936 1349 BRepExtrema_ExtFF aDeltaFace (aFaceA, aFaceB);
1350 if (!aDeltaFace.IsParallel())
1351 {
1352 std::cerr << "Error: the faces are not parallel.\n";
1353 return 1;
1354 }
af203d54 1355
404c8936 1356 TopExp_Explorer aFaceExpA (aFaceA, TopAbs_EDGE);
1357 TopExp_Explorer aFaceExpB (aFaceB, TopAbs_EDGE);
af203d54 1358
404c8936 1359 TopoDS_Edge anEdgeA = TopoDS::Edge (aFaceExpA.Current());
1360 TopoDS_Edge anEdgeB = TopoDS::Edge (aFaceExpB.Current());
af203d54 1361
404c8936 1362 BRepAdaptor_Curve aCurveA (anEdgeA);
1363 BRepAdaptor_Curve aCurveB (anEdgeB);
1364 gp_Pnt A = aCurveA.Value (0.1);
1365 gp_Pnt B = aCurveA.Value (0.9);
1366 gp_Pnt C = aCurveB.Value (0.5);
af203d54 1367
404c8936 1368 GC_MakePlane aMkPlane (A, B, C);
af203d54 1369
404c8936 1370 aRelation = new AIS_ParallelRelation (aFaceA, aFaceB, aMkPlane.Value());
1371 }
1372 break;
1373 }
af203d54 1374
404c8936 1375 case AIS_KOR_PERPENDICULAR:
1376 {
1377 if (aShapes.Extent() != 2)
1378 {
1379 std::cerr << "Error: Wrong number of selected shapes.\n";
1380 return 1;
1381 }
af203d54 1382
404c8936 1383 const TopoDS_Shape& aShapeA = aShapes.First();
1384 const TopoDS_Shape& aShapeB = aShapes.Last();
af203d54 1385
404c8936 1386 if (aShapeA.ShapeType() == TopAbs_EDGE)
1387 {
1388 TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
1389 TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
af203d54 1390
404c8936 1391 BRepAdaptor_Curve aCurveA (anEdgeA);
1392 BRepAdaptor_Curve aCurveB (anEdgeB);
af203d54 1393
404c8936 1394 gp_Pnt A = aCurveA.Value (0.1);
1395 gp_Pnt B = aCurveA.Value (0.9);
1396 gp_Pnt C = aCurveB.Value (0.5);
af203d54 1397
404c8936 1398 GC_MakePlane aMkPlane (A, B, C);
7fd59977 1399
404c8936 1400 aRelation = new AIS_PerpendicularRelation (anEdgeA, anEdgeB, aMkPlane.Value());
1401 }
1402 else
1403 {
1404 TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
1405 TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
7fd59977 1406
404c8936 1407 TopExp_Explorer aFaceExpA (aFaceA, TopAbs_EDGE);
1408 TopExp_Explorer aFaceExpB (aFaceB, TopAbs_EDGE);
7fd59977 1409
404c8936 1410 TopoDS_Edge anEdgeA = TopoDS::Edge (aFaceExpA.Current());
1411 TopoDS_Edge anEdgeB = TopoDS::Edge (aFaceExpB.Current());
7fd59977 1412
404c8936 1413 BRepAdaptor_Curve aCurveA (anEdgeA);
1414 BRepAdaptor_Curve aCurveB (anEdgeB);
7fd59977 1415
404c8936 1416 gp_Pnt A = aCurveA.Value (0.1);
1417 gp_Pnt B = aCurveA.Value (0.9);
1418 gp_Pnt C = aCurveB.Value (0.5);
7fd59977 1419
404c8936 1420 GC_MakePlane aMkPlane (A, B, C);
7fd59977 1421
404c8936 1422 aRelation = new AIS_PerpendicularRelation (aFaceA, aFaceB);
1423 }
1424
1425 break;
7fd59977 1426 }
7fd59977 1427
404c8936 1428 case AIS_KOR_TANGENT:
1429 {
1430 if (aShapes.Extent() != 2)
1431 {
1432 std::cerr << "Error: Wrong number of selected shapes.\n";
1433 return 1;
1434 }
7fd59977 1435
404c8936 1436 const TopoDS_Shape& aShapeA = aShapes.First();
1437 const TopoDS_Shape& aShapeB = aShapes.Last();
7fd59977 1438
404c8936 1439 if (aShapeA.ShapeType() == TopAbs_EDGE)
1440 {
1441 TopoDS_Edge anEdgeA = TopoDS::Edge (aShapeA);
1442 TopoDS_Edge anEdgeB = TopoDS::Edge (aShapeB);
7fd59977 1443
404c8936 1444 BRepAdaptor_Curve aCurveA (anEdgeA);
1445 BRepAdaptor_Curve aCurveB (anEdgeB);
7fd59977 1446
404c8936 1447 gp_Pnt A = aCurveA.Value (0.1);
1448 gp_Pnt B = aCurveA.Value (0.9);
1449 gp_Pnt C = aCurveB.Value (0.5);
7fd59977 1450
404c8936 1451 GC_MakePlane aMkPlane (A,B,C);
7fd59977 1452
404c8936 1453 aRelation = new AIS_TangentRelation (anEdgeA, anEdgeB, aMkPlane.Value());
1454 }
1455 else
1456 {
1457 TopoDS_Face aFaceA = TopoDS::Face (aShapeA);
1458 TopoDS_Face aFaceB = TopoDS::Face (aShapeB);
1459
1460 TopExp_Explorer aFaceExpA (aFaceA, TopAbs_EDGE);
1461 TopExp_Explorer aFaceExpB (aFaceB, TopAbs_EDGE);
7fd59977 1462
404c8936 1463 TopoDS_Edge anEdgeA = TopoDS::Edge (aFaceExpA.Current());
1464 TopoDS_Edge anEdgeB = TopoDS::Edge (aFaceExpB.Current());
1465
1466 BRepAdaptor_Curve aCurveA (anEdgeA);
1467 BRepAdaptor_Curve aCurveB (anEdgeB);
1468
1469 gp_Pnt A = aCurveA.Value (0.1);
1470 gp_Pnt B = aCurveA.Value (0.9);
1471 gp_Pnt C = aCurveB.Value (0.5);
1472
1473 GC_MakePlane aMkPlane (A,B,C);
1474
1475 aRelation = new AIS_TangentRelation (aFaceA, aFaceB, aMkPlane.Value());
1476 }
1477 break;
7fd59977 1478 }
7fd59977 1479
404c8936 1480 case AIS_KOR_SYMMETRIC:
1481 {
1482 if (aShapes.Extent() != 3)
1483 {
1484 std::cerr << "Error: Wrong number of selected shapes.\n";
1485 return 1;
1486 }
1487
1488 TopoDS_Shape aSelectedShapes[3];
1489 Standard_Integer anIdx = 0;
1490 TopTools_ListOfShape::Iterator anIter (aShapes);
1491 for (; anIter.More(); anIter.Next(), ++anIdx)
1492 {
1493 aSelectedShapes[anIdx] = anIter.Value();
1494 }
1495
1496 TopoDS_Edge anEdgeA = TopoDS::Edge (aSelectedShapes[0]);
1497 if (aSelectedShapes[1].ShapeType() == TopAbs_EDGE)
1498 {
1499 // 1 - edge, 2 - edge, 3 - edge.
1500 TopoDS_Edge anEdgeB = TopoDS::Edge (aSelectedShapes[1]);
1501 TopoDS_Edge anEdgeC = TopoDS::Edge (aSelectedShapes[2]);
1502
1503 BRepExtrema_ExtCC aDeltaEdgeAB (anEdgeA, anEdgeB);
1504 BRepExtrema_ExtCC aDeltaEdgeAC (anEdgeA, anEdgeC);
1505
1506 if (!aDeltaEdgeAB.IsParallel())
1507 {
1508 std::cerr << "Syntax error: the edges are not parallel.\n";
1509 return 1;
1510 }
1511 if (!aDeltaEdgeAC.IsParallel())
1512 {
1513 std::cerr << "Syntax error: the edges are not parallel.\n";
1514 return 1;
1515 }
1516
1517 TopoDS_Vertex Va, Vb, Vc, Vd;
1518 TopExp::Vertices (anEdgeB, Va, Vb);
1519 TopExp::Vertices (anEdgeC, Vc, Vd);
1520 gp_Pnt A = BRep_Tool::Pnt (Va);
1521 gp_Pnt B = BRep_Tool::Pnt (Vc);
1522 gp_Pnt C = Get3DPointAtMousePosition();
1523
1524 GC_MakePlane aMkPlane (A, B, C);
1525
1526 aRelation = new AIS_SymmetricRelation (anEdgeA, anEdgeB, anEdgeC, aMkPlane.Value());
1527 }
1528 else
1529 {
1530 // 1 - edge, 2 - vertex, 3 - vertex
1531 TopoDS_Vertex aVertexB = TopoDS::Vertex (aSelectedShapes[1]);
1532 TopoDS_Vertex aVertexC = TopoDS::Vertex (aSelectedShapes[2]);
1533
1534 gp_Pnt B = BRep_Tool::Pnt (aVertexB);
1535 gp_Pnt C = BRep_Tool::Pnt (aVertexC);
1536
1537 TopoDS_Vertex Va, Vb;
1538 TopExp::Vertices (anEdgeA, Va, Vb);
1539 gp_Pnt A = BRep_Tool::Pnt (Va);
1540
1541 GC_MakePlane aMkPlane(A, B, C);
1542 aRelation = new AIS_SymmetricRelation (anEdgeA, aVertexB, aVertexC, aMkPlane.Value());
1543 }
1544
1545 break;
7fd59977 1546 }
404c8936 1547
1548 case AIS_KOR_NONE:
1549 {
1550 std::cerr << "Error: Unknown type of relation!\n";
1551 return 1;
7fd59977 1552 }
7fd59977 1553 }
404c8936 1554
1555 VDisplayAISObject (aName, aRelation);
7fd59977 1556 return 0;
7fd59977 1557}
af203d54 1558
7fd59977 1559//=======================================================================
af203d54 1560//function : VDimParam
0499eb06 1561//purpose : Sets aspect parameters to dimension.
7fd59977 1562//=======================================================================
0499eb06 1563static int VDimParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
7fd59977 1564{
af203d54 1565 if (theArgNum < 3)
1566 {
1567 theDi << theArgVec[0] << " error: the wrong number of input parameters.\n";
1568 return 1;
1569 }
1570
0499eb06 1571
af203d54 1572 TCollection_AsciiString aName (theArgVec[1]);
0499eb06 1573 gp_Pln aWorkingPlane;
0499eb06 1574 Standard_Boolean isCustomPlane = Standard_False;
0499eb06 1575 Standard_Boolean toUpdate = Standard_True;
1576
1c9d1517 1577 NCollection_DataMap<TCollection_AsciiString, Standard_Real> aRealParams;
1578 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
1579
af203d54 1580 if (!GetMapOfAIS().IsBound2 (aName))
1581 {
1582 theDi << theArgVec[0] << "error: no object with this name.\n";
1583 return 1;
1584 }
1585
1586 Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2 (aName));
1587 if (anObject->Type() != AIS_KOI_Dimension)
1588 {
1589 theDi << theArgVec[0] << "error: no dimension with this name.\n";
1590 return 1;
1591 }
0499eb06 1592
af203d54 1593 Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (anObject);
1594 Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
1595
1c9d1517 1596 if (ParseDimensionParams (theArgNum, theArgVec, 2, anAspect,
1597 isCustomPlane, aWorkingPlane,
1598 aRealParams, aStringParams))
1599 {
1600 return 1;
1601 }
af203d54 1602
0499eb06 1603 if (isCustomPlane)
af203d54 1604 {
0499eb06 1605 aDim->SetCustomPlane (aWorkingPlane);
1606 }
af203d54 1607
1c9d1517 1608 SetDimensionParams (aDim, aRealParams, aStringParams);
af203d54 1609
0499eb06 1610 if (!aDim->IsValid())
1611 {
1612 std::cerr << "Error: Dimension geometry or plane is not valid.\n";
1613 return 1;
7fd59977 1614 }
af203d54 1615
1616 // Redisplay a dimension after parameter changing.
0499eb06 1617 if (ViewerTest::GetAISContext()->IsDisplayed (aDim))
1618 {
1619 ViewerTest::GetAISContext()->Redisplay (aDim, toUpdate);
1620 }
1621
af203d54 1622 return 0;
1623}
1624
ee905e84 1625//=======================================================================
1626//function : VAngleParam
1627//purpose : Sets aspect parameters to angle dimension.
1628//=======================================================================
1629static int VAngleParam (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
1630{
1631 if (theArgNum < 3)
1632 {
1633 theDi << theArgVec[0] << " error: the wrong number of input parameters.\n";
1634 return 1;
1635 }
1636
1637
1638 TCollection_AsciiString aName (theArgVec[1]);
1639 gp_Pln aWorkingPlane;
1640 Standard_Boolean toUpdate = Standard_True;
1641
1642 NCollection_DataMap<TCollection_AsciiString, TCollection_AsciiString> aStringParams;
1643
1644 if (!GetMapOfAIS().IsBound2 (aName))
1645 {
1646 theDi << theArgVec[0] << "error: no object with this name.\n";
1647 return 1;
1648 }
1649
1650 Handle(AIS_InteractiveObject) anObject = Handle(AIS_InteractiveObject)::DownCast(GetMapOfAIS().Find2 (aName));
1651 if (anObject->Type() != AIS_KOI_Dimension)
1652 {
1653 theDi << theArgVec[0] << "error: no dimension with this name.\n";
1654 return 1;
1655 }
1656
1657 Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (anObject);
1658 Handle(Prs3d_DimensionAspect) anAspect = aDim->DimensionAspect();
1659
1660 if (ParseAngleDimensionParams (theArgNum, theArgVec, 2, aStringParams))
1661 {
1662 return 1;
1663 }
1664
1665 SetAngleDimensionParams (aDim, aStringParams);
1666
1667 if (!aDim->IsValid())
1668 {
1669 std::cerr << "Error: Dimension geometry or plane is not valid.\n";
1670 return 1;
1671 }
1672
1673 // Redisplay a dimension after parameter changing.
1674 if (ViewerTest::GetAISContext()->IsDisplayed (aDim))
1675 {
1676 ViewerTest::GetAISContext()->Redisplay (aDim, toUpdate);
1677 }
1678 return 0;
1679}
1680
af203d54 1681//=======================================================================
1682//function : VMoveDim
1683//purpose : Moves dimension or relation text label to defined or picked
1684// position and updates the object.
1685//draw args: vmovedim [name] [x y z]
1686//=======================================================================
1687static int VMoveDim (Draw_Interpretor& theDi, Standard_Integer theArgNum, const char** theArgVec)
1688{
1689 if (theArgNum > 5)
1690 {
1691 theDi << theArgVec[0] << " error: the wrong number of parameters.\n";
7fd59977 1692 return 1;
af203d54 1693 }
1694
1695 // Parameters parsing
1696 Standard_Boolean isNameSet = (theArgNum ==2 || theArgNum == 5);
1697 Standard_Boolean isPointSet = (theArgNum == 4 || theArgNum == 5);
1698
1699 Handle(AIS_InteractiveObject) aPickedObj;
1700 gp_Pnt aPoint (gp::Origin());
af203d54 1701 Standard_Integer aMaxPickNum = 5;
1702
1703 // Find object
1704 if (isNameSet)
1705 {
1706 TCollection_AsciiString aName (theArgVec[1]);
1707 if (!GetMapOfAIS().IsBound2 (aName))
1708 {
1709 theDi << theArgVec[0] << " error: no object with this name.\n";
1710 return 1;
1711 }
1712
1713 aPickedObj = Handle(AIS_InteractiveObject)::DownCast (GetMapOfAIS().Find2 (aName));
1714
1715 if (aPickedObj.IsNull())
1716 {
1717 theDi << theArgVec[0] << " error: the object with this name is not valid.\n";
1718 return 1;
1719 }
1720
1721 if (aPickedObj->Type() != AIS_KOI_Dimension && aPickedObj->Type() != AIS_KOI_Relation)
1722 {
1723 theDi << theArgVec[0] << " error: no dimension or relation with this name.\n";
1724 return 1;
1725 }
1726 }
1727 else // Pick dimension or relation
1728 {
af203d54 1729 // Loop that will be handle picking.
1730 Standard_Integer anArgNum = 5;
1731 const char *aBuffer[] = { "VPick", "X", "VPickY","VPickZ", "VPickShape" };
1732 const char **anArgVec = (const char **) aBuffer;
1733
1734 Standard_Boolean isPicked = Standard_False;
1735 Standard_Integer aPickNum = 0;
1736 while (!isPicked && aPickNum < aMaxPickNum)
1737 {
1738 while (ViewerMainLoop (anArgNum, anArgVec)) { }
1739
1740 for (TheAISContext()->InitSelected(); TheAISContext()->MoreSelected(); TheAISContext()->NextSelected())
1741 {
1742 aPickedObj = TheAISContext()->SelectedInteractive();
1743 }
1744
1745 isPicked = (!aPickedObj.IsNull() && (aPickedObj->Type() == AIS_KOI_Dimension || aPickedObj->Type() == AIS_KOI_Relation));
1746
1747 if (isPicked)
1748 {
1749 break;
1750 }
1751 aPickNum++;
7fd59977 1752 }
af203d54 1753 if (!isPicked)
1754 {
586db386 1755 theDi << theArgVec[0] << ": no dimension or relation is selected.\n";
af203d54 1756 return 1;
7fd59977 1757 }
af203d54 1758 }
1759
1760 // Find point
1761 if (isPointSet)
1762 {
1763 aPoint = theArgNum == 4 ? gp_Pnt (atoi (theArgVec[1]), atoi (theArgVec[2]), atoi (theArgVec[3]))
1764 : gp_Pnt (atoi (theArgVec[2]), atoi (theArgVec[3]), atoi (theArgVec[4]));
1765 }
1766 else // Pick the point
1767 {
1768 Standard_Integer aPickArgNum = 5;
1769 const char *aPickBuff[] = {"VPick", "X", "VPickY", "VPickZ", "VPickShape"};
1770 const char **aPickArgVec = (const char **) aPickBuff;
1771
1772 while (ViewerMainLoop (aPickArgNum, aPickArgVec)) { }
1773
1774 // Set text position, update relation or dimension.
1775 if (aPickedObj->Type() == AIS_KOI_Relation)
1776 {
1777 Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (aPickedObj);
1778 aPoint = Get3DPointAtMousePosition();
1779 aRelation->SetPosition (aPoint);
0577ae8c 1780 TheAISContext()->Redisplay (aRelation, Standard_True);
af203d54 1781 }
1782 else
1783 {
1784 Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (aPickedObj);
1785 gp_Pnt aFirstPoint, aSecondPoint;
1786 if (aDim->KindOfDimension() == AIS_KOD_PLANEANGLE)
1787 {
1788 Handle(AIS_AngleDimension) anAngleDim = Handle(AIS_AngleDimension)::DownCast (aDim);
1789 aFirstPoint = anAngleDim->FirstPoint();
1790 aSecondPoint = anAngleDim->SecondPoint();
1791 }
1792 else if (aDim->KindOfDimension() == AIS_KOD_LENGTH)
1793 {
1794 Handle(AIS_LengthDimension) aLengthDim = Handle(AIS_LengthDimension)::DownCast (aDim);
1795 aFirstPoint = aLengthDim->FirstPoint();
1796 aSecondPoint = aLengthDim->SecondPoint();
1797 }
1798 else if (aDim->KindOfDimension() == AIS_KOD_RADIUS)
1799 {
1800 Handle(AIS_RadiusDimension) aRadiusDim = Handle(AIS_RadiusDimension)::DownCast (aDim);
1801 aFirstPoint = aRadiusDim->AnchorPoint();
1802 aSecondPoint = aRadiusDim->Circle().Location();
1803 }
1804 else if (aDim->KindOfDimension() == AIS_KOD_DIAMETER)
1805 {
1806 Handle(AIS_DiameterDimension) aDiameterDim = Handle(AIS_DiameterDimension)::DownCast (aDim);
1807 aFirstPoint = aDiameterDim->AnchorPoint();
1808 aSecondPoint = aDiameterDim->Circle().Location();
1809 }
1810
1811 if (!Get3DPointAtMousePosition (aFirstPoint, aSecondPoint, aPoint))
1812 {
1813 return 1;
7fd59977 1814 }
af203d54 1815
1816 aDim->SetTextPosition (aPoint);
0577ae8c 1817 TheAISContext()->Redisplay (aDim, Standard_True);
7fd59977 1818 }
af203d54 1819
7fd59977 1820 }
af203d54 1821
1822 // Set text position, update relation or dimension.
1823 if (aPickedObj->Type() == AIS_KOI_Relation)
1824 {
1825 Handle(AIS_Relation) aRelation = Handle(AIS_Relation)::DownCast (aPickedObj);
1826 aRelation->SetPosition (aPoint);
0577ae8c 1827 TheAISContext()->Redisplay (aRelation, Standard_True);
af203d54 1828 }
1829 else
1830 {
1831 Handle(AIS_Dimension) aDim = Handle(AIS_Dimension)::DownCast (aPickedObj);
1832 aDim->SetTextPosition (aPoint);
0577ae8c 1833 TheAISContext()->Redisplay (aDim, Standard_True);
af203d54 1834 }
1835
7fd59977 1836 return 0;
1837}
a6eb515f 1838
7fd59977 1839//=======================================================================
1840//function : RelationsCommands
1841//purpose :
1842//=======================================================================
1843
1844
1845void ViewerTest::RelationCommands(Draw_Interpretor& theCommands)
1846{
1847 const char *group = "AISRelations";
1848
1d7ca641 1849 theCommands.Add("vdimension",
404c8936 1850 "vdimension name {-angle|-length|-radius|-diameter}"
1851 "[-shapes shape1 [shape2 [shape3]]\n"
1852 "[-selected]\n"
7a733b19 1853 "[-text 3d|2d wf|sh|wireframe|shading IntegerSize]\n"
6fb1a930 1854 "[-font FontName]\n"
7a733b19 1855 "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
1856 "[-arrow external|internal|fit]\n"
1857 "[{-arrowlength|-arlen} RealArrowLength]\n"
1858 "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
0499eb06 1859 "[-plane xoy|yoz|zox]\n"
1860 "[-flyout FloatValue -extension FloatValue]\n"
73ddbb9a 1861 "[-autovalue]\n"
1862 "[-value CustomRealValue]\n"
1863 "[-textvalue CustomTextValue]\n"
1c9d1517 1864 "[-dispunits DisplayUnitsString]\n"
1865 "[-modelunits ModelUnitsString]\n"
1866 "[-showunits | -hideunits]\n"
1867 " -Builds angle, length, radius and diameter dimensions.\n"
1868 " -See also: vdimparam, vmovedim.\n",
a6eb515f 1869 __FILE__,VDimBuilder,group);
1870
404c8936 1871 theCommands.Add ("vrelation",
1872 "vrelation name {-concentric|-equaldistance|-equalradius|-fix|-identic|-offset|-parallel|-perpendicular|-tangent|-symmetric}"
1873 "\n\t\t: concentric - 2 circled edges."
1874 "\n\t\t: equaldistance - 4 vertex/edges."
1875 "\n\t\t: equalradius - 1 or 2 circled edges."
1876 "\n\t\t: fix - 1 edge."
1877 "\n\t\t: identic - 2 faces, edges or vertices."
1878 "\n\t\t: offset - 2 faces."
1879 "\n\t\t: parallel - 2 faces or 2 edges."
1880 "\n\t\t: perpendicular - 2 faces or 2 edges."
1881 "\n\t\t: tangent - two coplanar edges (first the circular edge then the tangent edge) or two faces."
1882 "\n\t\t: symmetric - 3 edges or 1 edge and 2 vertices."
1883 "-Builds specific relation from selected objects.",
1884 __FILE__, VRelationBuilder, group);
1885
af203d54 1886 theCommands.Add("vdimparam",
0499eb06 1887 "vdimparam name"
7a733b19 1888 "[-text 3d|2d wf|sh|wireframe|shading IntegerSize]\n"
6fb1a930 1889 "[-font FontName]\n"
7a733b19 1890 "[-label left|right|hcenter|hfit top|bottom|vcenter|vfit]\n"
1891 "[-arrow external|internal|fit]\n"
1892 "[{-arrowlength|-arlen} RealArrowLength]\n"
1893 "[{-arrowangle|-arangle} ArrowAngle(degrees)]\n"
0499eb06 1894 "[-plane xoy|yoz|zox]\n"
1895 "[-flyout FloatValue -extension FloatValue]\n"
1c9d1517 1896 "[-value CustomNumberValue]\n"
73ddbb9a 1897 "[-textvalue CustomTextValue]\n"
1c9d1517 1898 "[-dispunits DisplayUnitsString]\n"
1899 "[-modelunits ModelUnitsString]\n"
1900 "[-showunits | -hideunits]\n"
1901 " -Sets parameters for angle, length, radius and diameter dimensions.\n"
1902 " -See also: vmovedim, vdimension.\n",
af203d54 1903 __FILE__,VDimParam,group);
1904
ee905e84 1905 theCommands.Add("vangleparam",
1906 "vangleparam name"
1907 "[-type interior|exterior]\n"
1908 "[-showarrow first|second|both|none]\n",
1909 __FILE__,VAngleParam,group);
7fd59977 1910
1911 theCommands.Add("vmovedim",
faea8b40 1912 "vmovedim : vmovedim [name] [x y z]"
1913 "\n\t\t: Moves picked or named (if name defined)"
1914 "\n\t\t: dimension to picked mouse position or input point."
1915 "\n\t\t: Text label of dimension 'name' is moved to position, another parts of dimensionare adjusted.",
7fd59977 1916 __FILE__,VMoveDim,group);
1917
1918}