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