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