0027039: Draw Harness, ViewerTest - Fix rubber-band blinking
[occt.git] / src / AIS / AIS_RubberBand.cxx
CommitLineData
b12e1c7b 1// Created on: 2015-11-23
2// Created by: Anastasia BORISOVA
3// Copyright (c) 2015 OPEN CASCADE SAS
4//
5// This file is part of Open CASCADE Technology software library.
6//
7// This library is free software; you can redistribute it and/or modify it under
8// the terms of the GNU Lesser General Public License version 2.1 as published
9// by the Free Software Foundation, with special exception defined in the file
10// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
11// distribution for complete text of the license and disclaimer of any warranty.
12//
13// Alternatively, this file may be used under the terms of Open CASCADE
14// commercial license or contractual agreement.
15
16#include <AIS_RubberBand.hxx>
17#include <BRepMesh_DataStructureOfDelaun.hxx>
18#include <BRepMesh_Delaun.hxx>
19#include <Graphic3d_ArrayOfPolygons.hxx>
20#include <Graphic3d_ArrayOfPolylines.hxx>
21#include <Graphic3d_AspectFillArea3d.hxx>
22#include <Graphic3d_GraphicDriver.hxx>
23#include <Graphic3d_ArrayOfTriangles.hxx>
24#include <Graphic3d_TransModeFlags.hxx>
25#include <Graphic3d_ZLayerId.hxx>
26#include <Prs3d_LineAspect.hxx>
27#include <Prs3d_Root.hxx>
28#include <Prs3d_ShadingAspect.hxx>
29#include <SelectMgr_EntityOwner.hxx>
30#include <V3d_Viewer.hxx>
31#include <V3d_View.hxx>
32
33
34#define MEMORY_BLOCK_SIZE 512 * 7
35
36IMPLEMENT_STANDARD_RTTIEXT(AIS_RubberBand, AIS_InteractiveObject)
37//=======================================================================
38//function : Constructor
39//purpose :
40//=======================================================================
41AIS_RubberBand::AIS_RubberBand()
42{
43 myDrawer->SetLineAspect (new Prs3d_LineAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0));
44 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
69adb9ce 45 myDrawer->ShadingAspect()->SetMaterial (Graphic3d_NOM_PLASTIC);
b12e1c7b 46 myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_EMPTY);
47 myDrawer->ShadingAspect()->SetTransparency (1.0);
48 myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
49
50 SetTransformPersistence (Graphic3d_TMF_2d, gp_Pnt(-1, -1, 0));
51 SetZLayer (Graphic3d_ZLayerId_TopOSD);
52}
53
54//=======================================================================
55//function : Constructor
56//purpose :
57//=======================================================================
58AIS_RubberBand::AIS_RubberBand (const Quantity_Color& theLineColor,
59 const Aspect_TypeOfLine theLineType,
60 const Standard_Real theWidth)
61{
62 myDrawer->SetLineAspect (new Prs3d_LineAspect (theLineColor, theLineType, theWidth));
63 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
69adb9ce 64 myDrawer->ShadingAspect()->SetMaterial (Graphic3d_NOM_PLASTIC);
b12e1c7b 65 myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_EMPTY);
66 myDrawer->ShadingAspect()->SetTransparency (1.0);
67 myDrawer->ShadingAspect()->SetColor (Quantity_NOC_WHITE);
68
69 SetTransformPersistence (Graphic3d_TMF_2d, gp_Pnt(-1, -1, 0));
70 SetZLayer (Graphic3d_ZLayerId_TopOSD);
71}
72
73//=======================================================================
74//function : Constructor
75//purpose :
76//=======================================================================
77AIS_RubberBand::AIS_RubberBand (const Quantity_Color& theLineColor,
78 const Aspect_TypeOfLine theLineType,
79 const Quantity_Color theFillColor,
80 const Standard_Real theTransparency,
81 const Standard_Real theLineWidth)
82{
83 myDrawer->SetLineAspect (new Prs3d_LineAspect (theLineColor, theLineType, theLineWidth));
84 myDrawer->SetShadingAspect (new Prs3d_ShadingAspect());
69adb9ce 85 myDrawer->ShadingAspect()->SetMaterial (Graphic3d_NOM_PLASTIC);
b12e1c7b 86 myDrawer->ShadingAspect()->SetColor (theFillColor);
87 myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (Aspect_IS_SOLID);
88 myDrawer->ShadingAspect()->SetTransparency (theTransparency);
89
90 SetTransformPersistence (Graphic3d_TMF_2d, gp_Pnt(-1, -1, 0));
91 SetZLayer (Graphic3d_ZLayerId_TopOSD);
92}
93
94//=======================================================================
95//function : Destructor
96//purpose :
97//=======================================================================
98AIS_RubberBand::~AIS_RubberBand()
99{
100 myPoints.Clear();
101 myTriangles.Nullify();
102 myBorders.Nullify();
103}
104
105//=======================================================================
106//function : SetRectangle
107//purpose :
108//=======================================================================
109void AIS_RubberBand::SetRectangle (const Standard_Integer theMinX, const Standard_Integer theMinY,
110 const Standard_Integer theMaxX, const Standard_Integer theMaxY)
111{
112 myPoints.Clear();
113 myPoints.Append (Graphic3d_Vec2i (theMinX, theMinY));
114 myPoints.Append (Graphic3d_Vec2i (theMinX, theMaxY));
115 myPoints.Append (Graphic3d_Vec2i (theMaxX, theMaxY));
116 myPoints.Append (Graphic3d_Vec2i (theMaxX, theMinY));
117}
118
119//=======================================================================
120//function : AddPoint
121//purpose :
122//=======================================================================
123void AIS_RubberBand::AddPoint (const Graphic3d_Vec2i& thePoint)
124{
125 myPoints.Append (thePoint);
126}
127
128//=======================================================================
129//function : AddPoint
130//purpose :
131//=======================================================================
132void AIS_RubberBand::RemoveLastPoint()
133{
134 myPoints.Remove (myPoints.Length());
135}
136
137//=======================================================================
138//function : GetPoints
139//purpose :
140//=======================================================================
141const NCollection_Sequence<Graphic3d_Vec2i>& AIS_RubberBand::Points() const
142{
143 return myPoints;
144}
145
146//=======================================================================
147//function : LineColor
148//purpose :
149//=======================================================================
150Quantity_Color AIS_RubberBand::LineColor() const
151{
152 Quantity_Color aColor;
153 Standard_Real aWidth;
154 Aspect_TypeOfLine aTOL;
155 myDrawer->LineAspect()->Aspect()->Values (aColor, aTOL, aWidth);
156 return aColor;
157}
158
159//=======================================================================
160//function : SetLineColor
161//purpose :
162//=======================================================================
163void AIS_RubberBand::SetLineColor (const Quantity_Color& theColor)
164{
165 myDrawer->LineAspect()->SetColor (theColor);
166}
167
168//=======================================================================
169//function : FillColor
170//purpose :
171//=======================================================================
172Quantity_Color AIS_RubberBand::FillColor() const
173{
174 return myDrawer->ShadingAspect()->Color();
175}
176
177//=======================================================================
178//function : SetFillColor
179//purpose :
180//=======================================================================
181void AIS_RubberBand::SetFillColor (const Quantity_Color& theColor)
182{
183 myDrawer->ShadingAspect()->SetColor (theColor);
184}
185
186//=======================================================================
187//function : SetLineWidth
188//purpose :
189//=======================================================================
190void AIS_RubberBand::SetLineWidth (const Standard_Real theWidth) const
191{
192 myDrawer->LineAspect()->SetWidth (theWidth);
193}
194
195//=======================================================================
196//function : SetLineWidth
197//purpose :
198//=======================================================================
199Standard_Real AIS_RubberBand::LineWidth() const
200{
201 Quantity_Color aColor;
202 Standard_Real aWidth;
203 Aspect_TypeOfLine aTOL;
204 myDrawer->LineAspect()->Aspect()->Values (aColor, aTOL, aWidth);
205 return aWidth;
206}
207
208//=======================================================================
209//function : SetLineType
210//purpose :
211//=======================================================================
212void AIS_RubberBand::SetLineType (const Aspect_TypeOfLine theType)
213{
214 myDrawer->LineAspect()->SetTypeOfLine (theType);
215}
216
217//=======================================================================
218//function : LineType
219//purpose :
220//=======================================================================
221Aspect_TypeOfLine AIS_RubberBand::LineType() const
222{
223 Quantity_Color aColor;
224 Standard_Real aWidth;
225 Aspect_TypeOfLine aTOL;
226 myDrawer->LineAspect()->Aspect()->Values (aColor, aTOL, aWidth);
227 return aTOL;
228}
229
230//=======================================================================
231//function : SetFillTransparency
232//purpose :
233//=======================================================================
234void AIS_RubberBand::SetFillTransparency (const Standard_Real theValue) const
235{
236 myDrawer->ShadingAspect()->SetTransparency (theValue);
237}
238
239//=======================================================================
240//function : SetFillTransparency
241//purpose :
242//=======================================================================
243Standard_Real AIS_RubberBand::FillTransparency() const
244{
245 return myDrawer->ShadingAspect()->Transparency();
246}
247
248//=======================================================================
249//function : SetFilling
250//purpose :
251//=======================================================================
252void AIS_RubberBand::SetFilling (const Standard_Boolean theIsFilling)
253{
254 myDrawer->ShadingAspect()->Aspect()->SetInteriorStyle (theIsFilling ? Aspect_IS_SOLID : Aspect_IS_EMPTY);
255}
256
257//=======================================================================
258//function : SetFilling
259//purpose :
260//=======================================================================
261void AIS_RubberBand::SetFilling (const Quantity_Color theColor, const Standard_Real theTransparency)
262{
263 SetFilling (Standard_True);
264 SetFillTransparency (theTransparency);
265 SetFillColor (theColor);
266}
267
268//=======================================================================
269//function : IsFilling
270//purpose :
271//=======================================================================
272Standard_Boolean AIS_RubberBand::IsFilling() const
273{
274 Aspect_InteriorStyle aStyle;
275 Quantity_Color anIntColor, anEdgeColor;
276 Aspect_TypeOfLine aTOL;
277 Standard_Real aWidth;
278 myDrawer->ShadingAspect()->Aspect()->Values (aStyle, anIntColor, anEdgeColor, aTOL, aWidth);
279 return aStyle != Aspect_IS_EMPTY;
280}
281
282//=======================================================================
283//function : fillTriangles
284//purpose :
285//=======================================================================
286Standard_Boolean AIS_RubberBand::fillTriangles()
287{
288 Handle(NCollection_IncAllocator) anAllocator = new NCollection_IncAllocator (MEMORY_BLOCK_SIZE);
289 Handle(BRepMesh_DataStructureOfDelaun) aMeshStructure = new BRepMesh_DataStructureOfDelaun(anAllocator);
290 Standard_Integer aPtsLower = myPoints.Lower();
291 Standard_Integer aPtsUpper = myPoints.Upper();
292 BRepMesh::Array1OfInteger anIndexes (0, myPoints.Length() - 1);
293 for (Standard_Integer aPtIdx = aPtsLower; aPtIdx <= aPtsUpper; ++aPtIdx)
294 {
295 gp_XY aP ((Standard_Real)myPoints.Value (aPtIdx).x(),
296 (Standard_Real)myPoints.Value (aPtIdx).y());
297 BRepMesh_Vertex aVertex (aP, aPtIdx, BRepMesh_Frontier);
298 anIndexes.ChangeValue (aPtIdx - aPtsLower) = aMeshStructure->AddNode (aVertex);
299 }
300
301 Standard_Real aPtSum = 0;
302 for (Standard_Integer aIdx = aPtsLower; aIdx <= aPtsUpper; ++aIdx)
303 {
304 Standard_Integer aNextIdx = (aIdx % myPoints.Length()) + 1;
305 aPtSum += (Standard_Real)(myPoints.Value (aNextIdx).x() - myPoints.Value (aIdx).x())
306 * (Standard_Real)(myPoints.Value (aNextIdx).y() + myPoints.Value (aIdx).y());
307 }
308 Standard_Boolean isClockwiseOrdered = aPtSum < 0;
309
310 for (Standard_Integer aIdx = 0; aIdx < anIndexes.Length(); ++aIdx)
311 {
312 Standard_Integer aPtIdx = isClockwiseOrdered ? aIdx : (aIdx + 1) % anIndexes.Length();
313 Standard_Integer aNextPtIdx = isClockwiseOrdered ? (aIdx + 1) % anIndexes.Length() : aIdx;
314 BRepMesh_Edge anEdge (anIndexes.Value (aPtIdx),
315 anIndexes.Value (aNextPtIdx),
316 BRepMesh_Frontier);
317 aMeshStructure->AddLink (anEdge);
318 }
319
320 BRepMesh_Delaun aTriangulation (aMeshStructure, anIndexes);
321 const BRepMesh::MapOfInteger& aTriangles = aMeshStructure->ElementsOfDomain();
322 if (aTriangles.Extent() < 1)
323 return Standard_False;
324
325
326 Standard_Boolean toFill = Standard_False;
327 if (myTriangles.IsNull() || myTriangles->VertexNumber() != myPoints.Length() + 1)
328 {
329 toFill = Standard_True;
69adb9ce 330 myTriangles = new Graphic3d_ArrayOfTriangles (aTriangles.Extent() * 3, 0, Standard_True);
b12e1c7b 331 }
332
333 Standard_Integer aVertexIndex = 1;
334 BRepMesh::MapOfInteger::Iterator aTriangleIt (aTriangles);
335 for (; aTriangleIt.More(); aTriangleIt.Next())
336 {
337 const Standard_Integer aTriangleId = aTriangleIt.Key();
338 const BRepMesh_Triangle& aCurrentTriangle = aMeshStructure->GetElement (aTriangleId);
339
340 if (aCurrentTriangle.Movability() == BRepMesh_Deleted)
341 continue;
342
343 Standard_Integer aTriangleVerts[3];
344 aMeshStructure->ElementNodes (aCurrentTriangle, aTriangleVerts);
345
346 gp_Pnt2d aPts[3];
347 for (Standard_Integer aVertIdx = 0; aVertIdx < 3; ++aVertIdx)
348 {
349 const BRepMesh_Vertex& aVertex = aMeshStructure->GetNode (aTriangleVerts[aVertIdx]);
350 aPts[aVertIdx] = aVertex.Coord();
351 }
352
353 if (toFill)
354 {
69adb9ce 355 gp_Dir aNorm = gp::DZ();
b12e1c7b 356 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
357 {
69adb9ce 358 myTriangles->AddVertex (aPts[anIt].X(), aPts[anIt].Y(), 0.0,
359 aNorm.X(), aNorm.Y(), aNorm.Z());
b12e1c7b 360 }
361 }
362 else
363 {
364 for (Standard_Integer anIt = 0; anIt < 3; ++anIt)
365 {
366 myTriangles->SetVertice (aVertexIndex++, (Standard_ShortReal)aPts[anIt].X(), (Standard_ShortReal)aPts[anIt].Y(), 0.0f);
367 }
368 }
369 }
370
371 aMeshStructure.Nullify();
372 anAllocator.Nullify();
373
374 return Standard_True;
375}
376
377//=======================================================================
378//function : Compute
379//purpose :
380//=======================================================================
381void AIS_RubberBand::Compute (const Handle(PrsMgr_PresentationManager3d)& /*thePresentationManager*/,
382 const Handle(Prs3d_Presentation)& thePresentation,
383 const Standard_Integer /*theMode*/)
384{
385 Handle (Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation);
386
387 // Draw filling
388 if (IsFilling() && fillTriangles())
389 {
390 aGroup->SetGroupPrimitivesAspect (myDrawer->ShadingAspect()->Aspect());
391 aGroup->AddPrimitiveArray (myTriangles);
392 }
393
394 // Draw frame
395 if (myBorders.IsNull() || myBorders->VertexNumber() != myPoints.Length() + 1)
396 {
397 myBorders = new Graphic3d_ArrayOfPolylines (myPoints.Length() + 1);
398 for (Standard_Integer anIt = 1; anIt <= myPoints.Length(); anIt++)
399 {
400 myBorders->AddVertex ((Standard_Real)myPoints.Value (anIt).x(),
401 (Standard_Real)myPoints.Value (anIt).y(), 0.0);
402 }
403
404 myBorders->AddVertex ((Standard_Real)myPoints.Value(1).x(),
405 (Standard_Real)myPoints.Value(1).y(), 0.0);
406
407 }
408 else
409 {
410 for (Standard_Integer anIt = 1; anIt <= myPoints.Length(); anIt++)
411 {
412 myBorders->SetVertice (anIt, (Standard_ShortReal)myPoints.Value (anIt).x(),
413 (Standard_ShortReal)myPoints.Value (anIt).y(), 0.0f);
414 }
415
416 myBorders->SetVertice (myPoints.Length() + 1, (Standard_ShortReal)myPoints.Value(1).x(),
417 (Standard_ShortReal)myPoints.Value(1).y(), 0.0f);
418 }
419
420 aGroup->SetGroupPrimitivesAspect (myDrawer->LineAspect()->Aspect());
421 aGroup->AddPrimitiveArray (myBorders);
422}