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