1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-14 13:30:48 +03:00

Compare commits

..

20 Commits

Author SHA1 Message Date
oan
d7a6765b43 0025807: Bad performance of meshing
Added test cases
2019-07-10 19:45:21 +03:00
oan
9e4269d8e6 0029506: DRAW command "incmesh" hangs on the attached planar face with specified deflection.
Added test case
2019-07-10 19:00:30 +03:00
oan
5f55b8e615 0026074: BRepMesh_IncrementalMesh meshes a specific shape for a long time
Added test case
2019-07-10 18:59:28 +03:00
oan
057d4b15e3 0028089: Mesh - New algorithm for triangulation of 2d polygons
Added custom meshing core algorithm to generate base mesh using Delabella library:
https://github.com/msokalski/delabella

# Added CSF_MeshAlgo environment variable to select meshing core without necessity of recompilation
2019-07-10 13:04:25 +03:00
oan
4c04741d4c 0030827: Add common functionality allowing to switch triangulation algorithm in runtime
New classes BRepMesh_ConstrainedBaseMeshAlgo, BRepMesh_CustomBaseMeshAlgo and BRepMesh_CustomDelaunayBaseMeshAlgo are added.
These classes allow to add any custom triangulation algorithm to BRepMesh and perform post-processing and optimization of base mesh generated by those algorithms.
BRepMesh_Delaun: added possibility to process constraints when base mesh is generated by different algorithm.
BRepMesh_DelaunayNodeInsertionMeshAlgo: added PreProcessSurfaceNodes flag controlling addition of surface nodes (either before creation of base mesh or after) to gain maximum performance from triangulation algorithms.

Minor changes:
Use simple algorithm for cylinders when internal vertices mode is switched off to speed up computations.
BRepMesh_IncrementalMesh: added Perform method allowing to execute algorithm using manually created Context.
2019-07-08 15:40:36 +03:00
asl
0d56f7433b 0030824: Visualization, PrsMgr_PresentableObject - A new flag to disable automatic selection of children
A new flag myToPropagateVisualState is introduced for PrsMgr_PresentableObject: by default it is true, it means that the visual state (display/erase/color) should be propagated to all children. If false, the visual state is not propagated.
The flag can be set via the method ToPropagateVisualState() or via Draw command: "vparent <parent> -ignoreVisu"
2019-07-04 19:36:30 +03:00
tiv
acc6542a1b 0030820: Draw Harness, ViewerTest - vsetcolor has no effect on objects created by vsegment and vtriangle
MyPArrayObject class (an interactive object representing some array of primitives) is improved: a possibility of color changing is added to it.
2019-07-04 19:34:27 +03:00
kgv
803bdcdf2b 0030821: Data Exchange, RWGltf_CafReader - fallback to Mesh name in case of Node name is empty
Added option to use Mesh name as fallback, enabled by default.
2019-07-01 13:31:58 +03:00
emv
b6c113d0eb 0030817: Modeling Algorithms - BRepOffsetAPI_MakePipeShell produces invalid result
BRepFill_TrimShellCorner::CheckAndOrientEdges() - When orienting next edge in a sequence take into account the Orientation of the previous edge.
Test cases for the issue.
2019-06-27 16:07:14 +03:00
kgv
82c59511b4 0030811: Data Exchange, RWGltf_CafReader - fix inaccessibility of properties
Added missing Standard_EXPORT and getters.
Fixed metadata loss.
2019-06-26 18:49:23 +03:00
kgv
d9dd07545d 0030810: Data Exchange, RWObj_CafReader - fix material assignment
RWObj_MtlReader fixed incorrect folder iteration within findRelativePath().
Fixed discarding texture-only material.
RWObj_TriangulationReader::addMesh() - fixed usage of wrong material for flushing previous group.
2019-06-26 18:48:16 +03:00
emv
88c3accd1a 0030787: BRepOffsetAPI_MakePipeShell: hangs on the attached model
Protect IntTools_EdgeEdge::FindSolutions method from cases where splitting edge on parts does not give bounding box decreasing.
Use at least Epsilon from edges parameters as a step in BRepLib::FindValidRange.
Test case for the issue.
2019-06-25 19:47:09 +03:00
oan
3c1b70842d 0030780: [Regression to 7.3.0] BRepMesh fails triangulating one face of the shape
Added new parameter KeepSmallEdges to IMeshTools_Parameters allowing to compute min size for each edge locally, depending on the length of particular edge.
Parameter -smalledges now available for incmesh command.
2019-06-25 19:46:09 +03:00
kgv
62810a3c51 0030809: Data Exchange - fix misprint in RWMesh_CafReader::generateNames() 2019-06-25 19:45:05 +03:00
aba
bbf3fcdecd 0030806: Visualization - AIS Manipulator highlighting is not affected by the view affinity
- AIS_Manipalator object view affinity is now applied to presentation for highlighting.
2019-06-25 19:44:07 +03:00
kgv
e05d8d90c0 0030805: Visualization, StdSelect_BRepSelectionTool - empty sensitivity from polygon-only Edge
StdSelect_BRepSelectionTool::GetEdgeSensitive() now takes polygon points before creating curve Adaptor.
2019-06-25 19:42:49 +03:00
kgv
841aa8c47b 0030804: Foundation Classes - Poly_Connect crashes due to out-of-range array modification
Fixed initialization of edges array based on the wrong statement.
2019-06-25 19:41:23 +03:00
kgv
95bde2af7f 0030802: Draw Harness - add scrollbars to DFBrowse 2019-06-25 19:38:47 +03:00
msv
64a4475285 0029679: Draw Harness - Command 2dapprox works wrong when giving points in command line
Correct the behavior of the command 2dapprox for the case of points input in the command line.
Restore the work of the command 2dinterpole (implemented in the same method as 2dapprox).
Add test cases.
Correct generation of snapshots for the tests lowalgos/2dinter/*.
2019-06-24 19:22:47 +03:00
kgv
0c33a0bf4d 0030748: Visualization - Marker displayed in immediate layer ruins QT Quick view controls
OpenGl_Workspace::ResetAppliedAspect() now resets active texture unit to GL_TEXTURE0.
2019-06-22 19:50:10 +03:00
70 changed files with 2909 additions and 350 deletions

View File

@@ -5595,7 +5595,7 @@ Draw provides command to create curves and surfaces by approximation.
* **appro** fits a curve through 3d points;
* **surfapp** and **grilapp** fit a surface through 3d points by approximation;
* **surfint** fit a surface through 3d points by interpolation;
* **2dinterpolate** interpolates a curve.
* **2dinterpole** interpolates a curve.
@subsubsection occt_draw_6_8_1 appro, dapprox

View File

@@ -1035,15 +1035,21 @@ void AIS_Manipulator::HilightOwnerWithColor (const Handle(PrsMgr_PresentationMan
{
return;
}
aPresentation->CStructure()->ViewAffinity = thePM->StructureManager()->ObjectAffinity (Handle(Standard_Transient) (this));
if (anOwner->Mode() == AIS_MM_TranslationPlane)
{
Handle(Prs3d_Drawer) aStyle = new Prs3d_Drawer();
aStyle->SetColor(myAxes[anOwner->Index()].Color());
aStyle->SetTransparency(0.5);
aPresentation->Highlight(aStyle);
aStyle->SetColor (myAxes[anOwner->Index()].Color());
aStyle->SetTransparency (0.5);
aPresentation->Highlight (aStyle);
}
else
aPresentation->Highlight(theStyle);
{
aPresentation->Highlight (theStyle);
}
for (Graphic3d_SequenceOfGroup::Iterator aGroupIter (aPresentation->Groups());
aGroupIter.More(); aGroupIter.Next())
{

View File

@@ -55,6 +55,8 @@ static Standard_Boolean findNearestValidPoint(
//
// the general step is computed using general curve resolution
Standard_Real aStep = theCurve.Resolution(theTol) * 1.01;
if (aStep < theEps)
aStep = theEps;
// aD1Mag is a threshold to consider local derivative magnitude too small
// and to accelerate going out of sphere
// (inverse of resolution is the maximal derivative);
@@ -159,11 +161,19 @@ Standard_Boolean BRepLib::FindValidRange
if (theParV2 - theParV1 < Precision::PConfusion())
return Standard_False;
Standard_Real anEps = Max(Max(theCurve.Resolution(theTolE) * 0.1,
Epsilon(Max(Abs(theParV1), Abs(theParV2)))),
Precision::PConfusion());
Standard_Boolean isInfParV1 = Precision::IsInfinite (theParV1),
isInfParV2 = Precision::IsInfinite (theParV2);
if (Precision::IsInfinite(theParV1))
Standard_Real aMaxPar = 0.0;
if (!isInfParV1)
aMaxPar = Abs (theParV1);
if (!isInfParV2)
aMaxPar = Max (aMaxPar, Abs (theParV2));
Standard_Real anEps = Max (Max (theCurve.Resolution (theTolE) * 0.1, Epsilon (aMaxPar)),
Precision::PConfusion());
if (isInfParV1)
theFirst = theParV1;
else
{
@@ -174,7 +184,7 @@ Standard_Boolean BRepLib::FindValidRange
return Standard_False;
}
if (Precision::IsInfinite(theParV2))
if (isInfParV2)
theLast = theParV2;
else
{

View File

@@ -83,6 +83,12 @@ public:
myFaceMax = theMax;
}
//! Retruns true if cell filter contains no circle.
inline Standard_Boolean IsEmpty () const
{
return mySelector.Circles ().IsEmpty ();
}
//! Binds the circle to the tool.
//! @param theIndex index a circle should be bound with.
//! @param theCircle circle to be bound.

View File

@@ -0,0 +1,60 @@
// Created on: 2019-07-08
// Copyright (c) 2019 OPEN CASCADE SAS
// Created by: Oleg AGASHIN
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_ConstrainedBaseMeshAlgo_HeaderFile
#define _BRepMesh_ConstrainedBaseMeshAlgo_HeaderFile
#include <BRepMesh_BaseMeshAlgo.hxx>
#include <NCollection_Shared.hxx>
#include <IMeshTools_Parameters.hxx>
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_Delaun;
//! Class provides base fuctionality to build face triangulation using Dealunay approach.
//! Performs generation of mesh using raw data from model.
class BRepMesh_ConstrainedBaseMeshAlgo : public BRepMesh_BaseMeshAlgo
{
public:
//! Constructor.
BRepMesh_ConstrainedBaseMeshAlgo ()
{
}
//! Destructor.
virtual ~BRepMesh_ConstrainedBaseMeshAlgo ()
{
}
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_ConstrainedBaseMeshAlgo, BRepMesh_BaseMeshAlgo)
protected:
//! Returns size of cell to be used by acceleration circles grid structure.
virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer /*theVerticesNb*/)
{
return std::pair<Standard_Integer, Standard_Integer> (-1, -1);
}
//! Perfroms processing of generated mesh.
//! By default does nothing.
//! Expected to be called from method generateMesh() in successor classes.
virtual void postProcessMesh (BRepMesh_Delaun& /*theMesher*/)
{
}
};
#endif

View File

@@ -20,7 +20,9 @@
#include <BRepMesh_FaceDiscret.hxx>
#include <BRepMesh_ModelPreProcessor.hxx>
#include <BRepMesh_ModelPostProcessor.hxx>
#include <BRepMesh_MeshAlgoFactory.hxx>
#include <BRepMesh_DelabellaMeshAlgoFactory.hxx>
//=======================================================================
// Function: Constructor
@@ -28,11 +30,33 @@
//=======================================================================
BRepMesh_Context::BRepMesh_Context ()
{
enum MeshAlgo
{
MeshAlgo_Default = 0x0,
MeshAlgo_Delabella = 0x1
};
char* anAlgoVar;
anAlgoVar = getenv ("CSF_MeshAlgo");
const Standard_Integer anAlgoId = (anAlgoVar ? atoi (anAlgoVar) : MeshAlgo_Default);
Handle (IMeshTools_MeshAlgoFactory) aAlgoFactory;
switch (anAlgoId)
{
case MeshAlgo_Delabella:
aAlgoFactory = new BRepMesh_DelabellaMeshAlgoFactory;
break;
default:
aAlgoFactory = new BRepMesh_MeshAlgoFactory;
break;
}
SetModelBuilder (new BRepMesh_ModelBuilder);
SetEdgeDiscret (new BRepMesh_EdgeDiscret);
SetModelHealer (new BRepMesh_ModelHealer);
SetPreProcessor (new BRepMesh_ModelPreProcessor);
SetFaceDiscret (new BRepMesh_FaceDiscret(new BRepMesh_MeshAlgoFactory));
SetFaceDiscret (new BRepMesh_FaceDiscret (aAlgoFactory));
SetPostProcessor(new BRepMesh_ModelPostProcessor);
}

View File

@@ -26,6 +26,7 @@
#include <Adaptor3d_HCurveOnSurface.hxx>
#include <Adaptor2d_HCurve2d.hxx>
#include <Standard_Failure.hxx>
#include <GCPnts_AbscissaPoint.hxx>
//=======================================================================
//function : Constructor
@@ -79,21 +80,28 @@ void BRepMesh_CurveTessellator::init()
aPreciseLinDef *= 0.5;
}
aPreciseLinDef = Max(aPreciseLinDef, Precision::Confusion());
aPreciseAngDef = Max(aPreciseAngDef, Precision::Angular());
aPreciseLinDef = Max (aPreciseLinDef, Precision::Confusion());
aPreciseAngDef = Max (aPreciseAngDef, Precision::Angular());
Standard_Real aMinSize = myParameters.MinSize;
if (myParameters.AdjustMinSize)
{
aMinSize = Min (aMinSize, myParameters.RelMinSize() * GCPnts_AbscissaPoint::Length (
myCurve, myCurve.FirstParameter(), myCurve.LastParameter(), aPreciseLinDef));
}
mySquareEdgeDef = aPreciseLinDef * aPreciseLinDef;
mySquareMinSize = Max(mySquareEdgeDef, myParameters.MinSize * myParameters.MinSize);
mySquareMinSize = Max (mySquareEdgeDef, aMinSize * aMinSize);
myEdgeSqTol = BRep_Tool::Tolerance(myEdge);
myEdgeSqTol = BRep_Tool::Tolerance (myEdge);
myEdgeSqTol *= myEdgeSqTol;
const Standard_Integer aMinPntNb = (myCurve.GetType() == GeomAbs_Circle) ? 4 : 2; //OCC287
myDiscretTool.Initialize(myCurve,
myCurve.FirstParameter(), myCurve.LastParameter(),
aPreciseAngDef, aPreciseLinDef, aMinPntNb,
Precision::PConfusion(), myParameters.MinSize);
myDiscretTool.Initialize (myCurve,
myCurve.FirstParameter(), myCurve.LastParameter(),
aPreciseAngDef, aPreciseLinDef, aMinPntNb,
Precision::PConfusion(), aMinSize);
if (myCurve.IsCurveOnSurface())
{

View File

@@ -0,0 +1,93 @@
// Created on: 2019-06-07
// Copyright (c) 2019 OPEN CASCADE SAS
// Created by: Oleg AGASHIN
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_CustomBaseMeshAlgo_HeaderFile
#define _BRepMesh_CustomBaseMeshAlgo_HeaderFile
#include <BRepMesh_ConstrainedBaseMeshAlgo.hxx>
#include <NCollection_Shared.hxx>
#include <IMeshTools_Parameters.hxx>
#include <BRepMesh_Delaun.hxx>
#include <BRepMesh_MeshTool.hxx>
class BRepMesh_DataStructureOfDelaun;
//! Class provides base fuctionality to build face triangulation using custom triangulation algorithm.
//! Performs generation of mesh using raw data from model.
class BRepMesh_CustomBaseMeshAlgo : public BRepMesh_ConstrainedBaseMeshAlgo
{
public:
//! Constructor.
Standard_EXPORT BRepMesh_CustomBaseMeshAlgo ()
{
}
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_CustomBaseMeshAlgo ()
{
}
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_CustomBaseMeshAlgo, BRepMesh_ConstrainedBaseMeshAlgo)
protected:
//! Generates mesh for the contour stored in data structure.
Standard_EXPORT virtual void generateMesh () Standard_OVERRIDE
{
const Handle (BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure ();
const Standard_Integer aNodesNb = aStructure->NbNodes ();
buildBaseTriangulation ();
std::pair<Standard_Integer, Standard_Integer> aCellsCount = this->getCellsCount (aStructure->NbNodes ());
BRepMesh_Delaun aMesher (aStructure, aCellsCount.first, aCellsCount.second, Standard_False);
const Standard_Integer aNewNodesNb = aStructure->NbNodes ();
const Standard_Boolean isRemoveAux = aNewNodesNb > aNodesNb;
if (isRemoveAux)
{
IMeshData::VectorOfInteger aAuxVertices (aNewNodesNb - aNodesNb);
for (Standard_Integer aExtNodesIt = aNodesNb + 1; aExtNodesIt <= aNewNodesNb; ++aExtNodesIt)
{
aAuxVertices.Append (aExtNodesIt);
}
// Set aux vertices if there are some to clean up mesh correctly.
aMesher.SetAuxVertices (aAuxVertices);
}
aMesher.ProcessConstraints ();
// Destruction of triangles containing aux vertices added (possibly) during base mesh computation.
if (isRemoveAux)
{
aMesher.RemoveAuxElements ();
}
BRepMesh_MeshTool aCleaner (aStructure);
aCleaner.EraseFreeLinks ();
postProcessMesh (aMesher);
}
protected:
//! Builds base triangulation using custom triangulation algorithm.
Standard_EXPORT virtual void buildBaseTriangulation() = 0;
};
#endif

View File

@@ -0,0 +1,53 @@
// Created on: 2019-06-07
// Copyright (c) 2019 OPEN CASCADE SAS
// Created by: Oleg AGASHIN
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_CustomDelaunayBaseMeshAlgo_HeaderFile
#define _BRepMesh_CustomDelaunayBaseMeshAlgo_HeaderFile
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_Delaun;
//! Class provides base fuctionality to build face triangulation using custom
//! triangulation algorithm with possibility to modify final mesh.
//! Performs generation of mesh using raw data from model.
template<class BaseAlgo>
class BRepMesh_CustomDelaunayBaseMeshAlgo : public BaseAlgo
{
public:
//! Constructor.
BRepMesh_CustomDelaunayBaseMeshAlgo ()
{
}
//! Destructor.
virtual ~BRepMesh_CustomDelaunayBaseMeshAlgo ()
{
}
protected:
//! Perfroms processing of generated mesh.
virtual void postProcessMesh(BRepMesh_Delaun& theMesher)
{
BaseAlgo::postProcessMesh (theMesher);
const Handle(BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure();
std::pair<Standard_Integer, Standard_Integer> aCellsCount = this->getCellsCount (aStructure->NbNodes());
theMesher.InitCirclesTool (aCellsCount.first, aCellsCount.second);
}
};
#endif

View File

@@ -0,0 +1,155 @@
// Created on: 2019-07-05
// Copyright (c) 2019 OPEN CASCADE SAS
// Created by: Oleg AGASHIN
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepMesh_DelabellaBaseMeshAlgo.hxx>
#include <BRepMesh_MeshTool.hxx>
#include <BRepMesh_Delaun.hxx>
#include "delabella.h"
//=======================================================================
// Function: Constructor
// Purpose :
//=======================================================================
BRepMesh_DelabellaBaseMeshAlgo::BRepMesh_DelabellaBaseMeshAlgo ()
{
}
//=======================================================================
// Function: Destructor
// Purpose :
//=======================================================================
BRepMesh_DelabellaBaseMeshAlgo::~BRepMesh_DelabellaBaseMeshAlgo ()
{
}
//=======================================================================
//function : buildBaseTriangulation
//purpose :
//=======================================================================
void BRepMesh_DelabellaBaseMeshAlgo::buildBaseTriangulation()
{
const Handle(BRepMesh_DataStructureOfDelaun)& aStructure = this->getStructure();
Bnd_B2d aBox;
const Standard_Integer aNodesNb = aStructure->NbNodes ();
std::vector<Standard_Real> aPoints (2 * (aNodesNb + 4));
for (Standard_Integer aNodeIt = 0; aNodeIt < aNodesNb; ++aNodeIt)
{
const BRepMesh_Vertex& aVertex = aStructure->GetNode (aNodeIt + 1);
const size_t aBaseIdx = 2 * static_cast<size_t> (aNodeIt);
aPoints[aBaseIdx + 0] = aVertex.Coord ().X ();
aPoints[aBaseIdx + 1] = aVertex.Coord ().Y ();
aBox.Add (gp_Pnt2d(aVertex.Coord ()));
}
aBox.Enlarge (0.1 * (aBox.CornerMax () - aBox.CornerMin ()).Modulus ());
const gp_XY aMin = aBox.CornerMin ();
const gp_XY aMax = aBox.CornerMax ();
aPoints[2 * aNodesNb + 0] = aMin.X ();
aPoints[2 * aNodesNb + 1] = aMin.Y ();
aStructure->AddNode (BRepMesh_Vertex (
aPoints[2 * aNodesNb + 0],
aPoints[2 * aNodesNb + 1], BRepMesh_Free));
aPoints[2 * aNodesNb + 2] = aMax.X ();
aPoints[2 * aNodesNb + 3] = aMin.Y ();
aStructure->AddNode (BRepMesh_Vertex (
aPoints[2 * aNodesNb + 2],
aPoints[2 * aNodesNb + 3], BRepMesh_Free));
aPoints[2 * aNodesNb + 4] = aMax.X ();
aPoints[2 * aNodesNb + 5] = aMax.Y ();
aStructure->AddNode (BRepMesh_Vertex (
aPoints[2 * aNodesNb + 4],
aPoints[2 * aNodesNb + 5], BRepMesh_Free));
aPoints[2 * aNodesNb + 6] = aMin.X ();
aPoints[2 * aNodesNb + 7] = aMax.Y ();
aStructure->AddNode (BRepMesh_Vertex (
aPoints[2 * aNodesNb + 6],
aPoints[2 * aNodesNb + 7], BRepMesh_Free));
const Standard_Real aDiffX = (aMax.X () - aMin.X ());
const Standard_Real aDiffY = (aMax.Y () - aMin.Y ());
for (size_t i = 0; i < aPoints.size(); i += 2)
{
aPoints[i + 0] = (aPoints[i + 0] - aMin.X ()) / aDiffX - 0.5;
aPoints[i + 1] = (aPoints[i + 1] - aMin.Y ()) / aDiffY - 0.5;
}
IDelaBella* aTriangulator = IDelaBella::Create();
try
{
if (aTriangulator != NULL)
{
const int aVerticesNb = aTriangulator->Triangulate (
static_cast<int>(aPoints.size () / 2),
&aPoints[0], &aPoints[1], 2 * sizeof (Standard_Real));
if (aVerticesNb > 0)
{
const DelaBella_Triangle* aTrianglePtr = aTriangulator->GetFirstDelaunayTriangle();
while (aTrianglePtr != NULL)
{
Standard_Integer aNodes[3] = {
aTrianglePtr->v[0]->i + 1,
aTrianglePtr->v[2]->i + 1,
aTrianglePtr->v[1]->i + 1
};
Standard_Integer aEdges [3];
Standard_Boolean aOrientations[3];
for (Standard_Integer k = 0; k < 3; ++k)
{
const BRepMesh_Edge aLink (aNodes[k], aNodes[(k + 1) % 3], BRepMesh_Free);
const Standard_Integer aLinkInfo = aStructure->AddLink (aLink);
aEdges [k] = Abs (aLinkInfo);
aOrientations[k] = aLinkInfo > 0;
}
const BRepMesh_Triangle aTriangle (aEdges, aOrientations, BRepMesh_Free);
aStructure->AddElement (aTriangle);
aTrianglePtr = aTrianglePtr->next;
}
}
aTriangulator->Destroy ();
}
}
catch (Standard_Failure const& theException)
{
if (aTriangulator != NULL)
{
aTriangulator->Destroy ();
}
throw Standard_Failure (theException);
}
catch (...)
{
if (aTriangulator != NULL)
{
aTriangulator->Destroy ();
}
throw Standard_Failure ("BRepMesh_DelabellaBaseMeshAlgo::buildBaseTriangulation: exception in triangulation algorithm");
}
}

View File

@@ -0,0 +1,46 @@
// Created on: 2019-07-05
// Copyright (c) 2019 OPEN CASCADE SAS
// Created by: Oleg AGASHIN
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_DelabellaBaseMeshAlgo_HeaderFile
#define _BRepMesh_DelabellaBaseMeshAlgo_HeaderFile
#include <BRepMesh_CustomBaseMeshAlgo.hxx>
#include <NCollection_Shared.hxx>
#include <IMeshTools_Parameters.hxx>
class BRepMesh_DataStructureOfDelaun;
class BRepMesh_Delaun;
//! Class provides base fuctionality to build face triangulation using Delabella project.
//! Performs generation of mesh using raw data from model.
class BRepMesh_DelabellaBaseMeshAlgo : public BRepMesh_CustomBaseMeshAlgo
{
public:
//! Constructor.
Standard_EXPORT BRepMesh_DelabellaBaseMeshAlgo ();
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_DelabellaBaseMeshAlgo ();
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelabellaBaseMeshAlgo, BRepMesh_CustomBaseMeshAlgo)
protected:
//! Builds base triangulation using Delabella project.
Standard_EXPORT virtual void buildBaseTriangulation() Standard_OVERRIDE;
};
#endif

View File

@@ -0,0 +1,143 @@
// Created on: 2019-07-05
// Copyright (c) 2019 OPEN CASCADE SAS
// Created by: Oleg AGASHIN
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#include <BRepMesh_DelabellaMeshAlgoFactory.hxx>
#include <BRepMesh_DefaultRangeSplitter.hxx>
#include <BRepMesh_NURBSRangeSplitter.hxx>
#include <BRepMesh_SphereRangeSplitter.hxx>
#include <BRepMesh_CylinderRangeSplitter.hxx>
#include <BRepMesh_ConeRangeSplitter.hxx>
#include <BRepMesh_TorusRangeSplitter.hxx>
#include <BRepMesh_DelaunayBaseMeshAlgo.hxx>
#include <BRepMesh_DelabellaBaseMeshAlgo.hxx>
#include <BRepMesh_CustomDelaunayBaseMeshAlgo.hxx>
#include <BRepMesh_DelaunayNodeInsertionMeshAlgo.hxx>
#include <BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx>
#include <BRepMesh_BoundaryParamsRangeSplitter.hxx>
namespace
{
struct DefaultBaseMeshAlgo
{
typedef BRepMesh_DelaunayBaseMeshAlgo Type;
};
template<class RangeSplitter>
struct DefaultNodeInsertionMeshAlgo
{
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> Type;
};
struct BaseMeshAlgo
{
typedef BRepMesh_DelabellaBaseMeshAlgo Type;
};
template<class RangeSplitter>
struct NodeInsertionMeshAlgo
{
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BRepMesh_CustomDelaunayBaseMeshAlgo<BRepMesh_DelabellaBaseMeshAlgo> > Type;
};
template<class RangeSplitter>
struct DeflectionControlMeshAlgo
{
typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter, BRepMesh_CustomDelaunayBaseMeshAlgo<BRepMesh_DelabellaBaseMeshAlgo> > Type;
};
}
//=======================================================================
// Function: Constructor
// Purpose :
//=======================================================================
BRepMesh_DelabellaMeshAlgoFactory::BRepMesh_DelabellaMeshAlgoFactory ()
{
}
//=======================================================================
// Function: Destructor
// Purpose :
//=======================================================================
BRepMesh_DelabellaMeshAlgoFactory::~BRepMesh_DelabellaMeshAlgoFactory ()
{
}
//=======================================================================
// Function: GetAlgo
// Purpose :
//=======================================================================
Handle(IMeshTools_MeshAlgo) BRepMesh_DelabellaMeshAlgoFactory::GetAlgo(
const GeomAbs_SurfaceType theSurfaceType,
const IMeshTools_Parameters& theParameters) const
{
switch (theSurfaceType)
{
case GeomAbs_Plane:
return theParameters.InternalVerticesMode ?
new NodeInsertionMeshAlgo<BRepMesh_DefaultRangeSplitter>::Type :
new BaseMeshAlgo::Type;
break;
case GeomAbs_Sphere:
{
NodeInsertionMeshAlgo<BRepMesh_SphereRangeSplitter>::Type* aMeshAlgo =
new NodeInsertionMeshAlgo<BRepMesh_SphereRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
break;
case GeomAbs_Cylinder:
return theParameters.InternalVerticesMode ?
new DefaultNodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type :
new DefaultBaseMeshAlgo::Type;
break;
case GeomAbs_Cone:
{
NodeInsertionMeshAlgo<BRepMesh_ConeRangeSplitter>::Type* aMeshAlgo =
new NodeInsertionMeshAlgo<BRepMesh_ConeRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
break;
case GeomAbs_Torus:
{
NodeInsertionMeshAlgo<BRepMesh_TorusRangeSplitter>::Type* aMeshAlgo =
new NodeInsertionMeshAlgo<BRepMesh_TorusRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
break;
case GeomAbs_SurfaceOfRevolution:
{
DeflectionControlMeshAlgo<BRepMesh_BoundaryParamsRangeSplitter>::Type* aMeshAlgo =
new DeflectionControlMeshAlgo<BRepMesh_BoundaryParamsRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
break;
default:
{
DeflectionControlMeshAlgo<BRepMesh_NURBSRangeSplitter>::Type* aMeshAlgo =
new DeflectionControlMeshAlgo<BRepMesh_NURBSRangeSplitter>::Type;
aMeshAlgo->SetPreProcessSurfaceNodes (Standard_True);
return aMeshAlgo;
}
}
}

View File

@@ -0,0 +1,44 @@
// Created on: 2019-07-05
// Copyright (c) 2019 OPEN CASCADE SAS
// Created by: Oleg AGASHIN
//
// This file is part of Open CASCADE Technology software library.
//
// This library is free software; you can redistribute it and/or modify it under
// the terms of the GNU Lesser General Public License version 2.1 as published
// by the Free Software Foundation, with special exception defined in the file
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
// distribution for complete text of the license and disclaimer of any warranty.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
#ifndef _BRepMesh_DelabellaMeshAlgoFactory_HeaderFile
#define _BRepMesh_DelabellaMeshAlgoFactory_HeaderFile
#include <Standard_Transient.hxx>
#include <Standard_Type.hxx>
#include <GeomAbs_SurfaceType.hxx>
#include <IMeshTools_MeshAlgoFactory.hxx>
//! Implementation of IMeshTools_MeshAlgoFactory providing Delabella-based
//! algorithms of different compexity depending on type of target surface.
class BRepMesh_DelabellaMeshAlgoFactory : public IMeshTools_MeshAlgoFactory
{
public:
//! Constructor.
Standard_EXPORT BRepMesh_DelabellaMeshAlgoFactory ();
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_DelabellaMeshAlgoFactory ();
//! Creates instance of meshing algorithm for the given type of surface.
Standard_EXPORT virtual Handle(IMeshTools_MeshAlgo) GetAlgo(
const GeomAbs_SurfaceType theSurfaceType,
const IMeshTools_Parameters& theParameters) const Standard_OVERRIDE;
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelabellaMeshAlgoFactory, IMeshTools_MeshAlgoFactory)
};
#endif

View File

@@ -78,13 +78,34 @@ namespace {
}
} // anonymous namespace
//=======================================================================
//function : BRepMesh_Delaun
//purpose :
//=======================================================================
BRepMesh_Delaun::BRepMesh_Delaun (
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
const Standard_Integer theCellsCountU,
const Standard_Integer theCellsCountV,
const Standard_Boolean isFillCircles)
: myMeshData ( theOldMesh ),
myCircles (new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
if (isFillCircles)
{
InitCirclesTool (theCellsCountU, theCellsCountV);
}
}
//=======================================================================
//function : BRepMesh_Delaun
//purpose : Creates the triangulation with an empty Mesh data structure
//=======================================================================
BRepMesh_Delaun::BRepMesh_Delaun(IMeshData::Array1OfVertexOfDelaun& theVertices)
: myCircles (theVertices.Length(), new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE))
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
if ( theVertices.Length() > 2 )
{
@@ -103,7 +124,9 @@ BRepMesh_Delaun::BRepMesh_Delaun(
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
IMeshData::Array1OfVertexOfDelaun& theVertices)
: myMeshData( theOldMesh ),
myCircles ( theVertices.Length(), theOldMesh->Allocator() )
myCircles ( theVertices.Length(), new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
if ( theVertices.Length() > 2 )
{
@@ -119,7 +142,9 @@ BRepMesh_Delaun::BRepMesh_Delaun(
const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
IMeshData::VectorOfInteger& theVertexIndices)
: myMeshData( theOldMesh ),
myCircles ( theVertexIndices.Length(), theOldMesh->Allocator() )
myCircles ( theVertexIndices.Length(), new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
perform(theVertexIndices);
}
@@ -133,7 +158,9 @@ BRepMesh_Delaun::BRepMesh_Delaun (const Handle (BRepMesh_DataStructureOfDelaun)&
const Standard_Integer theCellsCountU,
const Standard_Integer theCellsCountV)
: myMeshData (theOldMesh),
myCircles (theVertexIndices.Length (), theOldMesh->Allocator ())
myCircles (theVertexIndices.Length (), new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE)),
mySupVert (3)
{
perform (theVertexIndices, theCellsCountU, theCellsCountV);
}
@@ -157,6 +184,63 @@ void BRepMesh_Delaun::Init(IMeshData::Array1OfVertexOfDelaun& theVertices)
perform( aVertexIndexes );
}
//=======================================================================
//function : InitCirclesTool
//purpose :
//=======================================================================
void BRepMesh_Delaun::InitCirclesTool (const Standard_Integer theCellsCountU,
const Standard_Integer theCellsCountV)
{
Bnd_Box2d aBox;
for (Standard_Integer aNodeIt = 1; aNodeIt <= myMeshData->NbNodes(); ++aNodeIt)
{
aBox.Add (gp_Pnt2d (GetVertex (aNodeIt).Coord ()));
}
aBox.Enlarge (Precision);
initCirclesTool (aBox, theCellsCountU, theCellsCountV);
IMeshData::IteratorOfMapOfInteger aTriangleIt (myMeshData->ElementsOfDomain());
for (; aTriangleIt.More(); aTriangleIt.Next())
{
Standard_Integer aNodesIndices[3];
const BRepMesh_Triangle& aTriangle = myMeshData->GetElement (aTriangleIt.Key());
myMeshData->ElementNodes (aTriangle, aNodesIndices);
myCircles.Bind (aTriangleIt.Key(),
GetVertex( aNodesIndices[0] ).Coord(),
GetVertex( aNodesIndices[1] ).Coord(),
GetVertex( aNodesIndices[2] ).Coord());
}
}
//=======================================================================
//function : initCirclesTool
//purpose :
//=======================================================================
void BRepMesh_Delaun::initCirclesTool (const Bnd_Box2d& theBox,
const Standard_Integer theCellsCountU,
const Standard_Integer theCellsCountV)
{
Standard_Real aMinX, aMinY, aMaxX, aMaxY;
theBox.Get ( aMinX, aMinY, aMaxX, aMaxY );
const Standard_Real aDeltaX = aMaxX - aMinX;
const Standard_Real aDeltaY = aMaxY - aMinY;
Standard_Integer aScaler = 2;
if ( myMeshData->NbNodes() > 100 )
{
aScaler = 5;
}
else if( myMeshData->NbNodes() > 1000 )
{
aScaler = 7;
}
myCircles.SetMinMaxSize( gp_XY( aMinX, aMinY ), gp_XY( aMaxX, aMaxY ) );
myCircles.SetCellSize ( aDeltaX / Max (theCellsCountU, aScaler),
aDeltaY / Max (theCellsCountV, aScaler));
}
//=======================================================================
//function : perform
//purpose : Create super mesh and run triangulation procedure
@@ -180,18 +264,8 @@ void BRepMesh_Delaun::perform(IMeshData::VectorOfInteger& theVertexIndices,
aBox.Enlarge (Precision);
Standard_Integer aScaler = 2;
if ( myMeshData->NbNodes() > 100 )
{
aScaler = 5;
}
else if( myMeshData->NbNodes() > 1000 )
{
aScaler = 7;
}
superMesh (aBox, Max (theCellsCountU, aScaler),
Max (theCellsCountV, aScaler));
initCirclesTool (aBox, theCellsCountU, theCellsCountV);
superMesh (aBox);
ComparatorOfIndexedVertexOfDelaun aCmp(myMeshData);
std::make_heap(theVertexIndices.begin(), theVertexIndices.end(), aCmp);
@@ -204,9 +278,7 @@ void BRepMesh_Delaun::perform(IMeshData::VectorOfInteger& theVertexIndices,
//function : superMesh
//purpose : Build the super mesh
//=======================================================================
void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
const Standard_Integer theCellsCountU,
const Standard_Integer theCellsCountV)
void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox)
{
Standard_Real aMinX, aMinY, aMaxX, aMaxY;
theBox.Get ( aMinX, aMinY, aMaxX, aMaxY );
@@ -217,17 +289,14 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
Standard_Real aDeltaMax = Max( aDeltaX, aDeltaY );
Standard_Real aDelta = aDeltaX + aDeltaY;
myCircles.SetMinMaxSize( gp_XY( aMinX, aMinY ), gp_XY( aMaxX, aMaxY ) );
myCircles.SetCellSize( aDeltaX / theCellsCountU, aDeltaY / theCellsCountV);
mySupVert.Append (myMeshData->AddNode(
BRepMesh_Vertex( ( aMinX + aMaxX ) / 2, aMaxY + aDeltaMax, BRepMesh_Free ) ) );
mySupVert[0] = myMeshData->AddNode(
BRepMesh_Vertex( ( aMinX + aMaxX ) / 2, aMaxY + aDeltaMax, BRepMesh_Free ) );
mySupVert.Append (myMeshData->AddNode(
BRepMesh_Vertex( aMinX - aDelta, aMinY - aDeltaMin, BRepMesh_Free ) ) );
mySupVert[1] = myMeshData->AddNode(
BRepMesh_Vertex( aMinX - aDelta, aMinY - aDeltaMin, BRepMesh_Free ) );
mySupVert[2] = myMeshData->AddNode(
BRepMesh_Vertex( aMaxX + aDelta, aMinY - aDeltaMin, BRepMesh_Free ) );
mySupVert.Append (myMeshData->AddNode(
BRepMesh_Vertex( aMaxX + aDelta, aMinY - aDeltaMin, BRepMesh_Free ) ) );
Standard_Integer e[3];
Standard_Boolean o[3];
@@ -236,7 +305,7 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
Standard_Integer aFirstNode = aNodeId;
Standard_Integer aLastNode = (aNodeId + 1) % 3;
Standard_Integer aLinkIndex = myMeshData->AddLink( BRepMesh_Edge(
mySupVert[aFirstNode], mySupVert[aLastNode], BRepMesh_Free ) );
mySupVert (aFirstNode), mySupVert (aLastNode), BRepMesh_Free ) );
e[aNodeId] = Abs(aLinkIndex);
o[aNodeId] = (aLinkIndex > 0);
@@ -254,7 +323,10 @@ void BRepMesh_Delaun::superMesh(const Bnd_Box2d& theBox,
void BRepMesh_Delaun::deleteTriangle(const Standard_Integer theIndex,
IMeshData::MapOfIntegerInteger& theLoopEdges )
{
myCircles.Delete( theIndex );
if (!myCircles.IsEmpty())
{
myCircles.Delete (theIndex);
}
const BRepMesh_Triangle& aElement = GetTriangle(theIndex);
const Standard_Integer(&e)[3] = aElement.myEdges;
@@ -279,8 +351,11 @@ void BRepMesh_Delaun::deleteTriangle(const Standard_Integer theIndex,
//=======================================================================
void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
{
// Insertion of edges of super triangles in the list of free edges:
IMeshData::MapOfIntegerInteger aLoopEdges(10, myMeshData->Allocator());
// Insertion of edges of super triangles in the list of free edges:
Handle(NCollection_IncAllocator) aAllocator = new NCollection_IncAllocator(
IMeshData::MEMORY_BLOCK_SIZE_HUGE);
IMeshData::MapOfIntegerInteger aLoopEdges(10, aAllocator);
const Standard_Integer(&e)[3] = mySupTrian.myEdges;
aLoopEdges.Bind( e[0], Standard_True );
@@ -297,28 +372,41 @@ void BRepMesh_Delaun::compute(IMeshData::VectorOfInteger& theVertexIndexes)
createTrianglesOnNewVertices( theVertexIndexes );
}
RemoveAuxElements ();
}
//=======================================================================
//function : RemoveAuxElements
//purpose :
//=======================================================================
void BRepMesh_Delaun::RemoveAuxElements ()
{
Handle (NCollection_IncAllocator) aAllocator = new NCollection_IncAllocator (
IMeshData::MEMORY_BLOCK_SIZE_HUGE);
IMeshData::MapOfIntegerInteger aLoopEdges (10, aAllocator);
// Destruction of triangles containing a top of the super triangle
BRepMesh_SelectorOfDataStructureOfDelaun aSelector( myMeshData );
for (Standard_Integer aSupVertId = 0; aSupVertId < 3; ++aSupVertId)
aSelector.NeighboursOfNode( mySupVert[aSupVertId] );
aLoopEdges.Clear();
IMeshData::IteratorOfMapOfInteger aFreeTriangles( aSelector.Elements() );
for ( ; aFreeTriangles.More(); aFreeTriangles.Next() )
deleteTriangle( aFreeTriangles.Key(), aLoopEdges );
BRepMesh_SelectorOfDataStructureOfDelaun aSelector (myMeshData);
for (Standard_Integer aSupVertId = 0; aSupVertId < mySupVert.Size(); ++aSupVertId)
aSelector.NeighboursOfNode (mySupVert (aSupVertId));
IMeshData::IteratorOfMapOfInteger aFreeTriangles (aSelector.Elements ());
for (; aFreeTriangles.More (); aFreeTriangles.Next ())
deleteTriangle (aFreeTriangles.Key (), aLoopEdges);
// All edges that remain free are removed from aLoopEdges;
// only the boundary edges of the triangulation remain there
IMeshData::MapOfIntegerInteger::Iterator aFreeEdges( aLoopEdges );
for ( ; aFreeEdges.More(); aFreeEdges.Next() )
IMeshData::MapOfIntegerInteger::Iterator aFreeEdges (aLoopEdges);
for (; aFreeEdges.More (); aFreeEdges.Next ())
{
if ( myMeshData->ElementsConnectedTo( aFreeEdges.Key() ).IsEmpty() )
myMeshData->RemoveLink( aFreeEdges.Key() );
if (myMeshData->ElementsConnectedTo (aFreeEdges.Key ()).IsEmpty ())
myMeshData->RemoveLink (aFreeEdges.Key ());
}
// The tops of the super triangle are destroyed
for (Standard_Integer aSupVertId = 0; aSupVertId < 3; ++aSupVertId)
myMeshData->RemoveNode( mySupVert[aSupVertId] );
for (Standard_Integer aSupVertId = 0; aSupVertId < mySupVert.Size (); ++aSupVertId)
myMeshData->RemoveNode (mySupVert (aSupVertId));
}
//=======================================================================
@@ -531,10 +619,7 @@ void BRepMesh_Delaun::createTrianglesOnNewVertices(
}
}
insertInternalEdges();
// Adjustment of meshes to boundary edges
frontierAdjust();
ProcessConstraints();
}
//=======================================================================
@@ -704,9 +789,7 @@ void BRepMesh_Delaun::cleanupMesh()
myMeshData->ElementNodes (aCurTriangle, v);
for (int aNodeIdx = 0; aNodeIdx < 3 && isCanNotBeRemoved; ++aNodeIdx)
{
if (v[aNodeIdx] == mySupVert[0] ||
v[aNodeIdx] == mySupVert[1] ||
v[aNodeIdx] == mySupVert[2])
if (isSupVertex (v[aNodeIdx]))
{
isCanNotBeRemoved = Standard_False;
}

View File

@@ -41,6 +41,12 @@ public:
DEFINE_STANDARD_ALLOC
//! Creates instance of triangulator, but do not run the algorithm automatically.
Standard_EXPORT BRepMesh_Delaun (const Handle(BRepMesh_DataStructureOfDelaun)& theOldMesh,
const Standard_Integer theCellsCountU,
const Standard_Integer theCellsCountV,
const Standard_Boolean isFillCircles);
//! Creates the triangulation with an empty Mesh data structure.
Standard_EXPORT BRepMesh_Delaun (IMeshData::Array1OfVertexOfDelaun& theVertices);
@@ -61,6 +67,10 @@ public:
//! Initializes the triangulation with an array of vertices.
Standard_EXPORT void Init (IMeshData::Array1OfVertexOfDelaun& theVertices);
//! Forces initialization of circles cell filter using working structure.
Standard_EXPORT void InitCirclesTool (const Standard_Integer theCellsCountU,
const Standard_Integer theCellsCountV);
//! Removes a vertex from the triangulation.
Standard_EXPORT void RemoveVertex (const BRepMesh_Vertex& theVertex);
@@ -77,6 +87,15 @@ public:
return myMeshData;
}
//! Forces insertion of constraint edges into the base triangulation.
inline void ProcessConstraints()
{
insertInternalEdges();
// Adjustment of meshes to boundary edges
frontierAdjust();
}
//! Gives the list of frontier edges.
inline Handle(IMeshData::MapOfInteger) Frontier() const
{
@@ -128,6 +147,17 @@ public:
const Standard_Real theSqTolerance,
Standard_Integer& theEdgeOn) const;
//! Explicitly sets ids of auxiliary vertices used to build mesh and used by 3rd-party algorithms.
inline void SetAuxVertices (const IMeshData::VectorOfInteger& theSupVert)
{
mySupVert = theSupVert;
}
//! Destruction of auxiliary triangles containing the given vertices.
//! Removes auxiliary vertices also.
//! @param theAuxVertices auxiliary vertices to be cleaned up.
Standard_EXPORT void RemoveAuxElements ();
private:
enum ReplaceFlag
@@ -139,6 +169,11 @@ private:
typedef NCollection_DataMap<Standard_Integer, IMeshData::MapOfInteger> DataMapOfMap;
//! Performs initialization of circles cell filter tool.
void initCirclesTool (const Bnd_Box2d& theBox,
const Standard_Integer theCellsCountU,
const Standard_Integer theCellsCountV);
//! Add boundig box for edge defined by start & end point to
//! the given vector of bounding boxes for triangulation edges.
void fillBndBox (IMeshData::SequenceOfBndB2d& theBoxes,
@@ -156,9 +191,7 @@ private:
const Standard_Integer theCellsCountV = -1);
//! Build the super mesh.
void superMesh (const Bnd_Box2d& theBox,
const Standard_Integer theCellsCountU,
const Standard_Integer theCellsCountV);
void superMesh (const Bnd_Box2d& theBox);
//! Computes the triangulation and adds the vertices,
//! edges and triangles to the Mesh data structure.
@@ -332,11 +365,25 @@ private:
//! Performs insertion of internal edges into mesh.
void insertInternalEdges();
//! Checks whether the given vertex id relates to super contour.
inline Standard_Boolean isSupVertex (const Standard_Integer theVertexIdx)
{
for (IMeshData::VectorOfInteger::Iterator aIt (mySupVert); aIt.More (); aIt.Next ())
{
if (theVertexIdx == aIt.Value ())
{
return Standard_True;
}
}
return Standard_False;
}
private:
Handle(BRepMesh_DataStructureOfDelaun) myMeshData;
BRepMesh_CircleTool myCircles;
Standard_Integer mySupVert[3];
IMeshData::VectorOfInteger mySupVert;
BRepMesh_Triangle mySupTrian;
};

View File

@@ -16,7 +16,7 @@
#ifndef _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
#define _BRepMesh_DelaunayBaseMeshAlgo_HeaderFile
#include <BRepMesh_BaseMeshAlgo.hxx>
#include <BRepMesh_ConstrainedBaseMeshAlgo.hxx>
#include <NCollection_Shared.hxx>
#include <IMeshTools_Parameters.hxx>
@@ -25,7 +25,7 @@ class BRepMesh_Delaun;
//! Class provides base fuctionality to build face triangulation using Dealunay approach.
//! Performs generation of mesh using raw data from model.
class BRepMesh_DelaunayBaseMeshAlgo : public BRepMesh_BaseMeshAlgo
class BRepMesh_DelaunayBaseMeshAlgo : public BRepMesh_ConstrainedBaseMeshAlgo
{
public:
@@ -35,24 +35,12 @@ public:
//! Destructor.
Standard_EXPORT virtual ~BRepMesh_DelaunayBaseMeshAlgo();
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_BaseMeshAlgo)
DEFINE_STANDARD_RTTI_INLINE(BRepMesh_DelaunayBaseMeshAlgo, BRepMesh_ConstrainedBaseMeshAlgo)
protected:
//! Returns size of cell to be used by acceleration circles grid structure.
virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer /*theVerticesNb*/)
{
return std::pair<Standard_Integer, Standard_Integer> (-1, -1);
}
//! Generates mesh for the contour stored in data structure.
Standard_EXPORT virtual void generateMesh() Standard_OVERRIDE;
//! Perfroms processing of generated mesh.
//! By default does nothing.
virtual void postProcessMesh(BRepMesh_Delaun& /*theMesher*/)
{
}
};
#endif

View File

@@ -22,12 +22,12 @@
//! Extends node insertion Delaunay meshing algo in order to control
//! deflection of generated trianges. Splits triangles failing the check.
template<class RangeSplitter>
class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter>
template<class RangeSplitter, class BaseAlgo>
class BRepMesh_DelaunayDeflectionControlMeshAlgo : public BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BaseAlgo>
{
private:
// Typedef for OCCT RTTI
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter> DelaunayInsertionBaseClass;
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BaseAlgo> DelaunayInsertionBaseClass;
public:

View File

@@ -21,17 +21,18 @@
//! Extends base Delaunay meshing algo in order to enable possibility
//! of addition of free vertices and internal nodes into the mesh.
template<class RangeSplitter>
class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo>
template<class RangeSplitter, class BaseAlgo>
class BRepMesh_DelaunayNodeInsertionMeshAlgo : public BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo>
{
private:
// Typedef for OCCT RTTI
typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> InsertionBaseClass;
typedef BRepMesh_NodeInsertionMeshAlgo<RangeSplitter, BaseAlgo> InsertionBaseClass;
public:
//! Constructor.
BRepMesh_DelaunayNodeInsertionMeshAlgo()
: myIsPreProcessSurfaceNodes (Standard_False)
{
}
@@ -40,8 +41,41 @@ public:
{
}
//! Returns PreProcessSurfaceNodes flag.
inline Standard_Boolean IsPreProcessSurfaceNodes () const
{
return myIsPreProcessSurfaceNodes;
}
//! Sets PreProcessSurfaceNodes flag.
//! If TRUE, registers surface nodes before generation of base mesh.
//! If FALSE, inserts surface nodes after generation of base mesh.
inline void SetPreProcessSurfaceNodes (const Standard_Boolean isPreProcessSurfaceNodes)
{
myIsPreProcessSurfaceNodes = isPreProcessSurfaceNodes;
}
protected:
//! Performs initialization of data structure using existing model data.
virtual Standard_Boolean initDataStructure() Standard_OVERRIDE
{
if (!InsertionBaseClass::initDataStructure())
{
return Standard_False;
}
if (myIsPreProcessSurfaceNodes)
{
const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
registerSurfaceNodes (aSurfaceNodes);
}
return Standard_True;
}
//! Returns size of cell to be used by acceleration circles grid structure.
virtual std::pair<Standard_Integer, Standard_Integer> getCellsCount (const Standard_Integer theVerticesNb) Standard_OVERRIDE
{
@@ -55,10 +89,13 @@ protected:
{
InsertionBaseClass::postProcessMesh(theMesher);
const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
if (!myIsPreProcessSurfaceNodes)
{
const Handle(IMeshData::ListOfPnt2d) aSurfaceNodes =
this->getRangeSplitter().GenerateSurfaceNodes(this->getParameters());
insertNodes(aSurfaceNodes, theMesher);
insertNodes(aSurfaceNodes, theMesher);
}
}
//! Inserts nodes into mesh.
@@ -86,6 +123,37 @@ protected:
theMesher.AddVertices(aVertexIndexes);
return !aVertexIndexes.IsEmpty();
}
private:
//! Registers surface nodes in data structure.
Standard_Boolean registerSurfaceNodes(
const Handle(IMeshData::ListOfPnt2d)& theNodes)
{
if (theNodes.IsNull() || theNodes->IsEmpty())
{
return Standard_False;
}
Standard_Boolean isAdded = Standard_False;
IMeshData::ListOfPnt2d::Iterator aNodesIt(*theNodes);
for (Standard_Integer aNodeIt = 1; aNodesIt.More(); aNodesIt.Next(), ++aNodeIt)
{
const gp_Pnt2d& aPnt2d = aNodesIt.Value();
if (this->getClassifier()->Perform(aPnt2d) == TopAbs_IN)
{
isAdded = Standard_True;
this->registerNode(this->getRangeSplitter().Point(aPnt2d),
aPnt2d, BRepMesh_Free, Standard_False);
}
}
return isAdded;
}
private:
Standard_Boolean myIsPreProcessSurfaceNodes;
};
#endif

View File

@@ -94,8 +94,6 @@ namespace
Handle(BRepMesh_FaceChecker::ArrayOfBndBoxTree)& myWiresBndBoxTree;
};
//! Selector.
//! Used to identify segments with overlapped bounding boxes.
//! Selector.
//! Used to identify segments with overlapped bounding boxes.
class BndBox2dTreeSelector : public IMeshData::BndBox2dTree::Selector

View File

@@ -86,19 +86,28 @@ BRepMesh_IncrementalMesh::~BRepMesh_IncrementalMesh()
//purpose :
//=======================================================================
void BRepMesh_IncrementalMesh::Perform()
{
Handle(BRepMesh_Context) aContext = new BRepMesh_Context;
Perform (aContext);
}
//=======================================================================
//function : Perform
//purpose :
//=======================================================================
void BRepMesh_IncrementalMesh::Perform(const Handle(IMeshTools_Context)& theContext)
{
initParameters();
Handle(BRepMesh_Context) aContext = new BRepMesh_Context;
aContext->SetShape(Shape());
aContext->ChangeParameters() = myParameters;
aContext->ChangeParameters().CleanModel = Standard_False;
theContext->SetShape(Shape());
theContext->ChangeParameters() = myParameters;
theContext->ChangeParameters().CleanModel = Standard_False;
IMeshTools_MeshBuilder aIncMesh(aContext);
IMeshTools_MeshBuilder aIncMesh(theContext);
aIncMesh.Perform();
myStatus = IMeshData_NoError;
const Handle(IMeshData_Model)& aModel = aContext->GetModel();
const Handle(IMeshData_Model)& aModel = theContext->GetModel();
for (Standard_Integer aFaceIt = 0; aFaceIt < aModel->FacesNb(); ++aFaceIt)
{
const IMeshData::IFaceHandle& aDFace = aModel->GetFace(aFaceIt);

View File

@@ -16,6 +16,7 @@
#include <BRepMesh_DiscretRoot.hxx>
#include <IMeshTools_Parameters.hxx>
#include <IMeshTools_Context.hxx>
//! Builds the mesh of a shape with respect of their
//! correctly triangulated parts
@@ -51,8 +52,11 @@ public: //! @name mesher API
Standard_EXPORT BRepMesh_IncrementalMesh(const TopoDS_Shape& theShape,
const IMeshTools_Parameters& theParameters);
//! Performs meshing ot the shape.
//! Performs meshing ot the shape.
Standard_EXPORT virtual void Perform() Standard_OVERRIDE;
//! Performs meshing using custom context;
Standard_EXPORT void Perform(const Handle(IMeshTools_Context)& theContext);
public: //! @name accessing to parameters.

View File

@@ -35,13 +35,13 @@ namespace
template<class RangeSplitter>
struct NodeInsertionMeshAlgo
{
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter> Type;
typedef BRepMesh_DelaunayNodeInsertionMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> Type;
};
template<class RangeSplitter>
struct DeflectionControlMeshAlgo
{
typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter> Type;
typedef BRepMesh_DelaunayDeflectionControlMeshAlgo<RangeSplitter, BRepMesh_DelaunayBaseMeshAlgo> Type;
};
}
@@ -82,7 +82,9 @@ Handle(IMeshTools_MeshAlgo) BRepMesh_MeshAlgoFactory::GetAlgo(
break;
case GeomAbs_Cylinder:
return new NodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type;
return theParameters.InternalVerticesMode ?
new NodeInsertionMeshAlgo<BRepMesh_CylinderRangeSplitter>::Type :
new BaseMeshAlgo::Type;
break;
case GeomAbs_Cone:

View File

@@ -0,0 +1,22 @@
MIT License
DELABELLA - Delaunay triangulation library
Copyright (C) 2018 GUMIX - Marcin Sokalski
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,5 +1,6 @@
BRepMesh_BaseMeshAlgo.cxx
BRepMesh_BaseMeshAlgo.hxx
BRepMesh_ConstrainedBaseMeshAlgo.hxx
BRepMesh_BoundaryParamsRangeSplitter.hxx
BRepMesh_Circle.hxx
BRepMesh_CircleInspector.hxx
@@ -82,4 +83,12 @@ BRepMesh_UVParamRangeSplitter.hxx
BRepMesh_Vertex.hxx
BRepMesh_VertexInspector.hxx
BRepMesh_VertexTool.cxx
BRepMesh_VertexTool.hxx
BRepMesh_VertexTool.hxx
BRepMesh_CustomBaseMeshAlgo.hxx
BRepMesh_CustomDelaunayBaseMeshAlgo.hxx
delabella.h
delabella.cpp
BRepMesh_DelabellaBaseMeshAlgo.hxx
BRepMesh_DelabellaBaseMeshAlgo.cxx
BRepMesh_DelabellaMeshAlgoFactory.hxx
BRepMesh_DelabellaMeshAlgoFactory.cxx

1021
src/BRepMesh/delabella.cpp Normal file

File diff suppressed because it is too large Load Diff

68
src/BRepMesh/delabella.h Normal file
View File

@@ -0,0 +1,68 @@
/*
DELABELLA - Delaunay triangulation library
Copyright (C) 2018 GUMIX - Marcin Sokalski
*/
#ifndef DELABELLA_H
#define DELABELLA_H
// returns: positive value: number of triangle indices, negative: number of line segment indices (degenerated input)
// triangle indices in abc array are always returned in clockwise order
// DEPRECIATED. move to new API either extern "C" or IDelaBella (C++)
int DelaBella(int points, const double* xy/*[points][2]*/, int* abc/*[2*points-5][3]*/, int (*errlog)(const char* fmt,...) = printf);
struct DelaBella_Vertex
{
int i; // index of original point
double x, y; // coordinates (input copy)
DelaBella_Vertex* next; // next silhouette vertex
};
struct DelaBella_Triangle
{
DelaBella_Vertex* v[3]; // 3 vertices spanning this triangle
DelaBella_Triangle* f[3]; // 3 adjacent faces, f[i] is at the edge opposite to vertex v[i]
DelaBella_Triangle* next; // next triangle (of delaunay set or hull set)
};
#ifdef __cplusplus
struct IDelaBella
{
static IDelaBella* Create();
virtual void Destroy() = 0;
virtual void SetErrLog(int(*proc)(void* stream, const char* fmt, ...), void* stream) = 0;
// return 0: no output
// negative: all points are colinear, output hull vertices form colinear segment list, no triangles on output
// positive: output hull vertices form counter-clockwise ordered segment contour, delaunay and hull triangles are available
// if 'y' pointer is null, y coords are treated to be located immediately after every x
// if advance_bytes is less than 2*sizeof coordinate type, it is treated as 2*sizeof coordinate type
virtual int Triangulate(int points, const float* x, const float* y = 0, int advance_bytes = 0) = 0;
virtual int Triangulate(int points, const double* x, const double* y = 0, int advance_bytes = 0) = 0;
// num of points passed to last call to Triangulate()
virtual int GetNumInputPoints() const = 0;
// num of verts returned from last call to Triangulate()
virtual int GetNumOutputVerts() const = 0;
virtual const DelaBella_Triangle* GetFirstDelaunayTriangle() const = 0; // valid only if Triangulate() > 0
virtual const DelaBella_Triangle* GetFirstHullTriangle() const = 0; // valid only if Triangulate() > 0
virtual const DelaBella_Vertex* GetFirstHullVertex() const = 0; // if Triangulate() < 0 it is list, otherwise closed contour!
};
#else
void* DelaBella_Create();
void DelaBella_Destroy(void* db);
void DelaBella_SetErrLog(void* db, int(*proc)(void* stream, const char* fmt, ...), void* stream);
int DelaBella_TriangulateFloat(void* db, int points, float* x, float* y = 0, int advance_bytes = 0);
int DelaBella_TriangulateDouble(void* db, int points, double* x, double* y = 0, int advance_bytes = 0);
int DelaBella_GetNumInputPoints(void* db);
int DelaBella_GetNumOutputVerts(void* db);
const DelaBella_Triangle* GetFirstDelaunayTriangle(void* db);
const DelaBella_Triangle* GetFirstHullTriangle(void* db);
const DelaBella_Vertex* GetFirstHullVertex(void* db);
#endif
#endif

View File

@@ -78,13 +78,19 @@ proc dftree { DDF_Browser } {
## ]
set w .$DDF_Browser
toplevel $w -height 400 -width 700 -background bisque3
toplevel $w -width 700 -height 400 -background bisque3
wm minsize $w 700 400
########
# Tree #
########
set tree1 [ttk::treeview $w.tree -show tree]
#set tree1 [ttk::treeview $w.tree -show tree]
set tree1 [ttk::treeview $w.tree -show tree -xscrollcommand "$w.tree.xscroll set" -yscrollcommand "$w.tree.yscroll set"]
set aScrollX [ttk::scrollbar $w.tree.xscroll -command "$w.tree xview" -orient horizontal]
set aScrollY [ttk::scrollbar $w.tree.yscroll -command "$w.tree yview"]
pack $aScrollX -side bottom -fill x
pack $aScrollY -side right -fill y
$tree1 tag bind Label <<TreeviewOpen>> [list DFTREE:Tree:Open $DDF_Browser $w]
$tree1 tag configure Label -font 9x15bold -foreground DarkGreen
#$tree1 tag configure Attribute -font 9x15 -background bisque3

View File

@@ -26,6 +26,7 @@
#include <DrawTrSurf_Curve2d.hxx>
#include <Geom2dAPI_ProjectPointOnCurve.hxx>
#include <Geom2dAPI_ExtremaCurveCurve.hxx>
#include <Geom2dAPI_Interpolate.hxx>
#include <Geom2dAPI_PointsToBSpline.hxx>
#include <Geom2dAPI_InterCurveCurve.hxx>
#include <Geom2d_Line.hxx>
@@ -178,7 +179,6 @@ static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const ch
else {
// test points ou ordonnees
hasPoints = Standard_False;
Standard_Integer nc = n - 3;
if (nc == 2 * Nb) {
// points
@@ -190,6 +190,7 @@ static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const ch
}
else if (nc - 2 == Nb) {
// YValues
hasPoints = Standard_False;
nc = 5;
X0 = Draw::Atof(a[3]);
DX = Draw::Atof(a[4]);
@@ -214,9 +215,44 @@ static Standard_Integer appro(Draw_Interpretor& di, Standard_Integer n, const ch
Handle(Geom2d_BSplineCurve) TheCurve;
if (hasPoints)
TheCurve = Geom2dAPI_PointsToBSpline(Points,Dmin,Dmax,GeomAbs_C2,Tol2d);
{
if (!strcmp (a[0], "2dinterpole"))
{
Geom2dAPI_Interpolate anInterpol (new TColgp_HArray1OfPnt2d(Points), Standard_False, Tol2d);
anInterpol.Perform();
if (!anInterpol.IsDone())
{
di << "not done";
return 1;
}
TheCurve = anInterpol.Curve();
}
else
{
Geom2dAPI_PointsToBSpline anApprox (Points, Dmin, Dmax, GeomAbs_C2, Tol2d);
if (!anApprox.IsDone())
{
di << "not done";
return 1;
}
TheCurve = anApprox.Curve();
}
}
else
TheCurve = Geom2dAPI_PointsToBSpline(YValues,X0,DX,Dmin,Dmax,GeomAbs_C2,Tol2d);
{
if (!strcmp (a[0], "2dinterpole"))
{
di << "incorrect usage";
return 1;
}
Geom2dAPI_PointsToBSpline anApprox (YValues, X0, DX, Dmin, Dmax, GeomAbs_C2, Tol2d);
if (!anApprox.IsDone())
{
di << "not done";
return 1;
}
TheCurve = anApprox.Curve();
}
DrawTrSurf::Set(a[1], TheCurve);
di << a[1];

View File

@@ -33,7 +33,8 @@ struct IMeshTools_Parameters {
Relative (Standard_False),
InternalVerticesMode (Standard_True),
ControlSurfaceDeflection (Standard_True),
CleanModel(Standard_True)
CleanModel (Standard_True),
AdjustMinSize (Standard_False)
{
}
@@ -78,6 +79,10 @@ struct IMeshTools_Parameters {
//! Cleans temporary data model when algorithm is finished.
Standard_Boolean CleanModel;
//! Enables/disables local adjustment of min size depending on edge size.
//! Disabled by default.
Standard_Boolean AdjustMinSize;
};
#endif

View File

@@ -304,7 +304,7 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
{
Standard_Boolean bIsClosed2;
Standard_Real aT11, aT12, aT21, aT22;
Bnd_Box aB2;
Bnd_Box aB1, aB2;
//
bSplit2 = Standard_False;
myRange1.Range(aT11, aT12);
@@ -313,7 +313,6 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
bIsClosed2 = IsClosed(myGeom2, aT21, aT22, myTol2, myRes2);
//
if (bIsClosed2) {
Bnd_Box aB1;
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
//
gp_Pnt aP = myGeom2->Value(aT21);
@@ -321,8 +320,9 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
}
//
if (!bIsClosed2) {
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
FindSolutions(myRange1, myRange2, aB2, theRanges1, theRanges2);
FindSolutions(myRange1, aB1, myRange2, aB2, theRanges1, theRanges2);
return;
}
//
@@ -343,10 +343,11 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
//
for (i = 1; i <= aNb1; ++i) {
const IntTools_Range& aR1 = aSegments1(i);
BndBuildBox(myCurve1, aR1.First(), aR1.Last(), myTol1, aB1);
for (j = 1; j <= aNb2; ++j) {
const IntTools_Range& aR2 = aSegments2(j);
BndBuildBox(myCurve2, aR2.First(), aR2.Last(), myTol2, aB2);
FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
FindSolutions(aR1, aB1, aR2, aB2, theRanges1, theRanges2);
}
}
//
@@ -358,6 +359,7 @@ void IntTools_EdgeEdge::FindSolutions(IntTools_SequenceOfRanges& theRanges1,
//purpose :
//=======================================================================
void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
const Bnd_Box& theBox1,
const IntTools_Range& theR2,
const Bnd_Box& theBox2,
IntTools_SequenceOfRanges& theRanges1,
@@ -373,6 +375,7 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
theR1.Range(aT11, aT12);
theR2.Range(aT21, aT22);
//
aB1 = theBox1;
aB2 = theBox2;
//
bThin = Standard_False;
@@ -385,9 +388,7 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
aTB21 = aT21;
aTB22 = aT22;
//
//1. Build box for first edge and find parameters
// of the second one in that box
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
//1. Find parameters of the second edge in the box of first one
bOut = aB1.IsOut(aB2);
if (bOut) {
break;
@@ -435,7 +436,9 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
((aT21 - aTB21) < aSmallStep2) && ((aTB22 - aT22) < aSmallStep2)) {
bStop = Standard_True;
}
//
else
BndBuildBox (myCurve1, aT11, aT12, myTol1, aB1);
} while (!bStop);
//
if (bOut) {
@@ -498,13 +501,20 @@ void IntTools_EdgeEdge::FindSolutions(const IntTools_Range& theR1,
Standard_Integer i, aNb1;
IntTools_SequenceOfRanges aSegments1;
//
// Build box for first curve to compare
// the boxes of the splits with this one
BndBuildBox(myCurve1, aT11, aT12, myTol1, aB1);
const Standard_Real aB1SqExtent = aB1.SquareExtent();
//
IntTools_Range aR2(aT21, aT22);
BndBuildBox(myCurve2, aT21, aT22, myTol2, aB2);
//
aNb1 = SplitRangeOnSegments(aT11, aT12, myRes1, 3, aSegments1);
for (i = 1; i <= aNb1; ++i) {
const IntTools_Range& aR1 = aSegments1(i);
FindSolutions(aR1, aR2, aB2, theRanges1, theRanges2);
BndBuildBox(myCurve1, aR1.First(), aR1.Last(), myTol1, aB1);
if (!aB1.IsOut(aB2) && (aNb1 == 1 || aB1.SquareExtent() < aB1SqExtent))
FindSolutions(aR1, aB1, aR2, aB2, theRanges1, theRanges2);
}
}

View File

@@ -146,7 +146,8 @@ protected:
//! Looking for the exact intersection ranges
Standard_EXPORT void FindSolutions (const IntTools_Range& theR1,
Standard_EXPORT void FindSolutions (
const IntTools_Range& theR1, const Bnd_Box& theBox1,
const IntTools_Range& theR2, const Bnd_Box& theBox2,
IntTools_SequenceOfRanges& theRanges1, IntTools_SequenceOfRanges& theRanges2);

View File

@@ -88,7 +88,7 @@ options:\n\
-surf_def_off disables control of deflection of mesh from real\n\
surface (enabled by default)\n\
-parallel enables parallel execution (switched off by default)\n\
-adaptive enables adaptive computation of minimal value in parametric space\n";
-adjust_min enables local adjustment of min size depending on edge size (switched off by default)\n";
return 0;
}
@@ -121,6 +121,8 @@ options:\n\
aMeshParams.InternalVerticesMode = Standard_False;
else if (aOpt == "-surf_def_off")
aMeshParams.ControlSurfaceDeflection = Standard_False;
else if (aOpt == "-adjust_min")
aMeshParams.AdjustMinSize = Standard_True;
else if (i < nbarg)
{
Standard_Real aVal = Draw::Atof(argv[i++]);

View File

@@ -204,6 +204,10 @@ void OpenGl_Workspace::ResetAppliedAspect()
ApplyAspects();
myGlContext->SetTypeOfLine (myDefaultAspects.Aspect()->LineType());
myGlContext->SetLineWidth (myDefaultAspects.Aspect()->LineWidth());
if (myGlContext->core15fwd != NULL)
{
myGlContext->core15fwd->glActiveTexture (GL_TEXTURE0);
}
}
// =======================================================================

View File

@@ -76,13 +76,13 @@ void Poly_Connect::Load (const Handle(Poly_Triangulation)& theTriangulation)
mysense = false;
mymore = false;
const Standard_Integer nbNodes = myTriangulation->NbNodes();
const Standard_Integer nbTriangles = myTriangulation->NbTriangles();
const Standard_Integer aNbNodes = myTriangulation->NbNodes();
const Standard_Integer aNbTris = myTriangulation->NbTriangles();
{
const Standard_Integer aNbAdjs = 6 * nbTriangles;
if (myTriangles.Size() != nbNodes)
const Standard_Integer aNbAdjs = 6 * aNbTris;
if (myTriangles.Size() != aNbNodes)
{
myTriangles.Resize (1, nbNodes, Standard_False);
myTriangles.Resize (1, aNbNodes, Standard_False);
}
if (myAdjacents.Size() != aNbAdjs)
{
@@ -95,118 +95,117 @@ void Poly_Connect::Load (const Handle(Poly_Triangulation)& theTriangulation)
// We first build an array of the list of edges connected to the nodes
// create an array to store the edges starting from the vertices
Standard_Integer i;
// the last node is not used because edges are stored at the lower node index
polyedge** edges = new polyedge*[nbNodes];
for (i = 0; i < nbNodes; i++) edges[i] = 0;
NCollection_Array1<polyedge*> anEdges (1, aNbNodes);
anEdges.Init (NULL);
// loop on the triangles
Standard_Integer j,k,n[3],n1,n2;
const Poly_Array1OfTriangle& triangles = myTriangulation->Triangles();
for (i = 1; i <= nbTriangles; i++) {
NCollection_Vec3<Standard_Integer> aTriNodes;
NCollection_Vec2<Standard_Integer> anEdgeNodes;
for (Standard_Integer aTriIter = 1; aTriIter <= aNbTris; ++aTriIter)
{
// get the nodes
triangles(i).Get(n[0],n[1],n[2]);
myTriangulation->Triangle (aTriIter).Get (aTriNodes[0], aTriNodes[1], aTriNodes[2]);
// Update the myTriangles array
myTriangles(n[0]) = i;
myTriangles(n[1]) = i;
myTriangles(n[2]) = i;
myTriangles.SetValue (aTriNodes[0], aTriIter);
myTriangles.SetValue (aTriNodes[1], aTriIter);
myTriangles.SetValue (aTriNodes[2], aTriIter);
// update the edge lists
for (j = 0; j < 3; j++) {
k = (j+1) % 3; // the following node of the edge
if (n[j] <= n[k]) {
n1 = n[j];
n2 = n[k];
for (Standard_Integer aNodeInTri = 0; aNodeInTri < 3; ++aNodeInTri)
{
const Standard_Integer aNodeNext = (aNodeInTri + 1) % 3; // the following node of the edge
if (aTriNodes[aNodeInTri] < aTriNodes[aNodeNext])
{
anEdgeNodes[0] = aTriNodes[aNodeInTri];
anEdgeNodes[1] = aTriNodes[aNodeNext];
}
else {
n1 = n[k];
n2 = n[j];
else
{
anEdgeNodes[0] = aTriNodes[aNodeNext];
anEdgeNodes[1] = aTriNodes[aNodeInTri];
}
// edge from n1 to n2 with n1 < n2
// insert in the list of n1
polyedge* ced = edges[n1];
while (ced != 0) {
// the edge already exists
if (ced->nd == n2)
break;
else
ced = ced->next;
// edge from node 0 to node 1 with node 0 < node 1
// insert in the list of node 0
polyedge* ced = anEdges[anEdgeNodes[0]];
for (; ced != NULL; ced = ced->next)
{
// the edge already exists
if (ced->nd == anEdgeNodes[1])
{
// just mark the adjacency if found
ced->nt[1] = aTriIter;
ced->nn[1] = aTriNodes[3 - aNodeInTri - aNodeNext]; // the third node
break;
}
}
if (ced == 0) {
// create the edge if not found
ced = new polyedge;
ced->next = edges[n1];
edges[n1] = ced;
ced->nd = n2;
ced->nt[0] = i;
ced->nn[0] = n[3-j-k]; // the third node
ced->nt[1] = 0;
ced->nn[1] = 0;
}
else {
// just mark the adjacency if found
ced->nt[1] = i;
ced->nn[1] = n[3-j-k]; // the third node
if (ced == NULL)
{
// create the edge if not found
ced = new polyedge();
ced->next = anEdges[anEdgeNodes[0]];
anEdges[anEdgeNodes[0]] = ced;
ced->nd = anEdgeNodes[1];
ced->nt[0] = aTriIter;
ced->nn[0] = aTriNodes[3 - aNodeInTri - aNodeNext]; // the third node
ced->nt[1] = 0;
ced->nn[1] = 0;
}
}
}
// now complete the myAdjacents array
Standard_Integer index = 1;
for (i = 1; i <= nbTriangles; i++) {
Standard_Integer anAdjIndex = 1;
for (Standard_Integer aTriIter = 1; aTriIter <= aNbTris; ++aTriIter)
{
// get the nodes
triangles(i).Get(n[0],n[1],n[2]);
myTriangulation->Triangle (aTriIter).Get (aTriNodes[0], aTriNodes[1], aTriNodes[2]);
// fore each edge
for (j = 0; j < 3; j++) {
k = (j+1) % 3; // the following node of the edge
if (n[j] <= n[k]) {
n1 = n[j];
n2 = n[k];
// for each edge in triangle
for (Standard_Integer aNodeInTri = 0; aNodeInTri < 3; ++aNodeInTri)
{
const Standard_Integer aNodeNext = (aNodeInTri + 1) % 3; // the following node of the edge
if (aTriNodes[aNodeInTri] < aTriNodes[aNodeNext])
{
anEdgeNodes[0] = aTriNodes[aNodeInTri];
anEdgeNodes[1] = aTriNodes[aNodeNext];
}
else {
n1 = n[k];
n2 = n[j];
else
{
anEdgeNodes[0] = aTriNodes[aNodeNext];
anEdgeNodes[1] = aTriNodes[aNodeInTri];
}
// edge from n1 to n2 with n1 < n2
// find in the list of n1
polyedge* ced = edges[n1];
while (ced->nd != n2)
ced = ced->next;
// edge from node 0 to node 1 with node 0 < node 1
// find in the list of node 0
const polyedge* ced = anEdges[anEdgeNodes[0]];
while (ced->nd != anEdgeNodes[1])
{
ced = ced->next;
}
// Find the adjacent triangle
Standard_Integer l = 0;
if (ced->nt[0] == i) l = 1;
myAdjacents(index) = ced->nt[l];
myAdjacents(index+3) = ced->nn[l];
index++;
const Standard_Integer l = ced->nt[0] == aTriIter ? 1 : 0;
myAdjacents.SetValue (anAdjIndex, ced->nt[l]);
myAdjacents.SetValue (anAdjIndex + 3, ced->nn[l]);
++anAdjIndex;
}
index += 3;
anAdjIndex += 3;
}
// destroy the edges array
for (i = 0; i < nbNodes; i++) {
polyedge* ced = edges[i];
while (ced != 0) {
polyedge* tmp = ced->next;
delete ced;
ced = tmp;
for (Standard_Integer aNodeIter = anEdges.Lower(); aNodeIter <= anEdges.Upper(); ++aNodeIter)
{
for (polyedge* anEdgeIter = anEdges[aNodeIter]; anEdgeIter != NULL;)
{
polyedge* aTmp = anEdgeIter->next;
delete anEdgeIter;
anEdgeIter = aTmp;
}
}
delete [] edges;
}
//=======================================================================

View File

@@ -56,7 +56,8 @@ PrsMgr_PresentableObject::PrsMgr_PresentableObject (const PrsMgr_TypeOfPresentat
//
myInfiniteState (Standard_False),
myIsMutable (Standard_False),
myHasOwnPresentations (Standard_True)
myHasOwnPresentations (Standard_True),
myToPropagateVisualState (Standard_True)
{
myDrawer->SetDisplayMode (-1);
}

View File

@@ -528,6 +528,14 @@ public: //! @name deprecated methods
Standard_DEPRECATED("This method is deprecated - TransformPersistence() should be called instead")
Standard_EXPORT gp_Pnt GetTransformPersistencePoint() const;
//! Get value of the flag "propagate visual state"
//! It means that the display/erase/color visual state is propagated automatically to all children;
//! by default, the flag is true
Standard_Boolean ToPropagateVisualState() const { return myToPropagateVisualState; }
//! Change the value of the flag "propagate visual state"
void SetPropagateVisualState(const Standard_Boolean theFlag) { myToPropagateVisualState = theFlag; }
protected:
//! Recomputes all presentations of the object.
@@ -569,6 +577,7 @@ protected:
Standard_Boolean myIsMutable; //!< mutable flag
Standard_Boolean myHasOwnPresentations; //!< flag indicating if object should have own presentations
Standard_Boolean myToPropagateVisualState; //!< flag indicating if visual state (display/erase/color) should be propagated to all children
};
DEFINE_STANDARD_HANDLE(PrsMgr_PresentableObject, Standard_Transient)

View File

@@ -69,9 +69,12 @@ void PrsMgr_PresentationManager::Display (const Handle(PrsMgr_PresentableObject)
thePrsObj->Compute (this, Handle(Prs3d_Presentation)(), theMode);
}
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
Display (anIter.Value(), theMode);
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
Display(anIter.Value(), theMode);
}
}
}
@@ -82,9 +85,12 @@ void PrsMgr_PresentationManager::Display (const Handle(PrsMgr_PresentableObject)
void PrsMgr_PresentationManager::Erase (const Handle(PrsMgr_PresentableObject)& thePrsObj,
const Standard_Integer theMode)
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
Erase (anIter.Value(), theMode);
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
Erase(anIter.Value(), theMode);
}
}
PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
@@ -124,9 +130,12 @@ void PrsMgr_PresentationManager::Erase (const Handle(PrsMgr_PresentableObject)&
void PrsMgr_PresentationManager::Clear (const Handle(PrsMgr_PresentableObject)& thePrsObj,
const Standard_Integer theMode)
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
Clear (anIter.Value(), theMode);
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
Clear(anIter.Value(), theMode);
}
}
const Handle(PrsMgr_Presentation) aPrs = Presentation (thePrsObj, theMode);
@@ -144,9 +153,12 @@ void PrsMgr_PresentationManager::SetVisibility (const Handle(PrsMgr_PresentableO
const Standard_Integer theMode,
const Standard_Boolean theValue)
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
SetVisibility (anIter.Value(), theMode, theValue);
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
SetVisibility(anIter.Value(), theMode, theValue);
}
}
if (!thePrsObj->HasOwnPresentations())
{
@@ -166,9 +178,12 @@ void PrsMgr_PresentationManager::SetVisibility (const Handle(PrsMgr_PresentableO
// =======================================================================
void PrsMgr_PresentationManager::Unhighlight (const Handle(PrsMgr_PresentableObject)& thePrsObj)
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
Unhighlight (anIter.Value());
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
Unhighlight(anIter.Value());
}
}
const PrsMgr_Presentations& aPrsList = thePrsObj->Presentations();
@@ -192,9 +207,12 @@ void PrsMgr_PresentationManager::SetDisplayPriority (const Handle(PrsMgr_Present
const Standard_Integer theMode,
const Standard_Integer theNewPrior) const
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
SetDisplayPriority (anIter.Value(), theMode, theNewPrior);
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
SetDisplayPriority(anIter.Value(), theMode, theNewPrior);
}
}
const Handle(PrsMgr_Presentation) aPrs = Presentation (thePrsObj, theMode);
@@ -211,12 +229,15 @@ void PrsMgr_PresentationManager::SetDisplayPriority (const Handle(PrsMgr_Present
Standard_Integer PrsMgr_PresentationManager::DisplayPriority (const Handle(PrsMgr_PresentableObject)& thePrsObj,
const Standard_Integer theMode) const
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
Standard_Integer aPriority = DisplayPriority (anIter.Value(), theMode);
if (aPriority != 0)
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
return aPriority;
Standard_Integer aPriority = DisplayPriority(anIter.Value(), theMode);
if (aPriority != 0)
{
return aPriority;
}
}
}
@@ -233,11 +254,14 @@ Standard_Integer PrsMgr_PresentationManager::DisplayPriority (const Handle(PrsMg
Standard_Boolean PrsMgr_PresentationManager::IsDisplayed (const Handle(PrsMgr_PresentableObject)& thePrsObj,
const Standard_Integer theMode) const
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
if (IsDisplayed (anIter.Value(), theMode))
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
return Standard_True;
if (IsDisplayed(anIter.Value(), theMode))
{
return Standard_True;
}
}
}
@@ -253,11 +277,14 @@ Standard_Boolean PrsMgr_PresentationManager::IsDisplayed (const Handle(PrsMgr_Pr
Standard_Boolean PrsMgr_PresentationManager::IsHighlighted (const Handle(PrsMgr_PresentableObject)& thePrsObj,
const Standard_Integer theMode) const
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
if (IsHighlighted (anIter.Value(), theMode))
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
return Standard_True;
if (IsHighlighted(anIter.Value(), theMode))
{
return Standard_True;
}
}
}
@@ -523,10 +550,14 @@ Standard_Boolean PrsMgr_PresentationManager::RemovePresentation (const Handle(Pr
void PrsMgr_PresentationManager::SetZLayer (const Handle(PrsMgr_PresentableObject)& thePrsObj,
const Graphic3d_ZLayerId theLayerId)
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
SetZLayer (anIter.Value(), theLayerId);
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
SetZLayer(anIter.Value(), theLayerId);
}
}
if (!thePrsObj->HasOwnPresentations())
{
return;
@@ -579,9 +610,12 @@ void PrsMgr_PresentationManager::Color (const Handle(PrsMgr_PresentableObject)&
const Handle(PrsMgr_PresentableObject)& theSelObj,
const Standard_Integer theImmediateStructLayerId)
{
for (PrsMgr_ListOfPresentableObjectsIter anIter (thePrsObj->Children()); anIter.More(); anIter.Next())
if (thePrsObj->ToPropagateVisualState())
{
Color (anIter.Value(), theStyle, theMode, NULL, theImmediateStructLayerId);
for (PrsMgr_ListOfPresentableObjectsIter anIter(thePrsObj->Children()); anIter.More(); anIter.Next())
{
Color(anIter.Value(), theStyle, theMode, NULL, theImmediateStructLayerId);
}
}
if (!thePrsObj->HasOwnPresentations())
{

View File

@@ -103,7 +103,9 @@ private:
// Purpose :
//================================================================
RWGltf_CafReader::RWGltf_CafReader()
: myToParallel (false)
: myToParallel (false),
myToSkipEmptyNodes (true),
myUseMeshNameAsFallback (true)
{
myCoordSysConverter.SetInputLengthUnit (1.0); // glTF defines model in meters
myCoordSysConverter.SetInputCoordinateSystem (RWMesh_CoordinateSystem_glTF);
@@ -215,8 +217,11 @@ Standard_Boolean RWGltf_CafReader::performMesh (const TCollection_AsciiString& t
aDoc.SetFilePath (theFile);
aDoc.SetProbeHeader (theToProbe);
aDoc.SetExternalFiles (myExternalFiles);
aDoc.SetMetadata (myMetadata);
aDoc.SetErrorPrefix (anErrPrefix);
aDoc.SetCoordinateSystemConverter (myCoordSysConverter);
aDoc.SetSkipEmptyNodes (myToSkipEmptyNodes);
aDoc.SetMeshNameAsFallback (myUseMeshNameAsFallback);
if (!theToProbe)
{
aDoc.SetAttributeMap (myAttribMap);

View File

@@ -36,6 +36,18 @@ public:
//! Setup multithreaded execution.
void SetParallel (bool theToParallel) { myToParallel = theToParallel; }
//! Return TRUE if Nodes without Geometry should be ignored, TRUE by default.
bool ToSkipEmptyNodes() { return myToSkipEmptyNodes; }
//! Set flag to ignore nodes without Geometry.
void SetSkipEmptyNodes (bool theToSkip) { myToSkipEmptyNodes = theToSkip; }
//! Set flag to use Mesh name in case if Node name is empty, TRUE by default.
bool ToUseMeshNameAsFallback() { return myUseMeshNameAsFallback; }
//! Set flag to use Mesh name in case if Node name is empty.
void SetMeshNameAsFallback (bool theToFallback) { myUseMeshNameAsFallback = theToFallback; }
protected:
//! Read the mesh from specified file.
@@ -58,7 +70,9 @@ protected:
protected:
Standard_Boolean myToParallel; //!< flag to use multithreading; FALSE by default
Standard_Boolean myToParallel; //!< flag to use multithreading; FALSE by default
Standard_Boolean myToSkipEmptyNodes; //!< ignore nodes without Geometry; TRUE by default
Standard_Boolean myUseMeshNameAsFallback; //!< flag to use Mesh name in case if Node name is empty, TRUE by default
};

View File

@@ -171,6 +171,7 @@ RWGltf_GltfJsonParser::RWGltf_GltfJsonParser (TopTools_SequenceOfShape& theRootS
myIsBinary (false),
myIsGltf1 (false),
myToSkipEmptyNodes (true),
myUseMeshNameAsFallback (true),
myToProbeHeader (false)
{
myCSTrsf.SetInputLengthUnit (1.0); // meters
@@ -250,18 +251,23 @@ void RWGltf_GltfJsonParser::gltfParseAsset()
}
}
if (myMetadata == NULL)
{
return;
}
if (const RWGltf_JsonValue* aGenerator = findObjectMember (*anAsset, "generator"))
{
if (aGenerator->IsString())
{
myMetadata.Add ("generator", aGenerator->GetString());
myMetadata->Add ("generator", aGenerator->GetString());
}
}
if (const RWGltf_JsonValue* aCopyRight = findObjectMember (*anAsset, "copyright"))
{
if (aCopyRight->IsString())
{
myMetadata.Add ("copyright", aCopyRight->GetString());
myMetadata->Add ("copyright", aCopyRight->GetString());
}
}
}
@@ -1582,6 +1588,43 @@ void RWGltf_GltfJsonParser::bindNamedShape (TopoDS_Shape& theShape,
{
aShapeAttribs.Style.SetColorSurf (aLateData->BaseColor());
}
if (aShapeAttribs.Name.IsEmpty()
&& myUseMeshNameAsFallback)
{
// fallback using Mesh name
aShapeAttribs.Name = aLateData->Name();
}
}
}
else if (aShapeAttribs.Name.IsEmpty()
&& myUseMeshNameAsFallback)
{
// fallback using Mesh name
TopLoc_Location aDummy;
TCollection_AsciiString aMeshName;
for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
{
if (Handle(RWGltf_GltfLatePrimitiveArray) aLateData = Handle(RWGltf_GltfLatePrimitiveArray)::DownCast (BRep_Tool::Triangulation (TopoDS::Face (aFaceIter.Value()), aDummy)))
{
if (aLateData->Name().IsEmpty())
{
aMeshName.Clear();
break;
}
else if (aMeshName.IsEmpty())
{
aMeshName = aLateData->Name();
}
else if (!aMeshName.IsEqual (aLateData->Name()))
{
aMeshName.Clear();
break;
}
}
}
if (!aMeshName.IsEmpty())
{
aShapeAttribs.Name = aMeshName;
}
}
myAttribMap->Bind (theShape, aShapeAttribs);

View File

@@ -87,6 +87,9 @@ public:
//! Set list for storing external files.
void SetExternalFiles (NCollection_IndexedMap<TCollection_AsciiString>& theExternalFiles) { myExternalFiles = &theExternalFiles; }
//! Set metadata map.
void SetMetadata (TColStd_IndexedDataMapOfStringString& theMetadata) { myMetadata = &theMetadata; }
//! Return transformation from glTF to OCCT coordinate system.
const RWMesh_CoordinateSystemConverter& CoordinateSystemConverter() const { return myCSTrsf; }
@@ -102,12 +105,15 @@ public:
myBinBodyLen = theBinBodyLen;
}
//! Set flag to ignore nodes without Geometry, TRUE by default.
void SetSkipEmptyNodes (bool theToSkip) { myToSkipEmptyNodes = theToSkip; }
//! Set flag to use Mesh name in case if Node name is empty, TRUE by default.
void SetMeshNameAsFallback (bool theToFallback) { myUseMeshNameAsFallback = theToFallback; }
//! Parse glTF document.
Standard_EXPORT bool Parse (const Handle(Message_ProgressIndicator)& theProgress);
//! Return metadata map.
const TColStd_IndexedDataMapOfStringString& Metadata() const { return myMetadata; }
//! Return face list for loading triangulation.
NCollection_Vector<TopoDS_Face>& FaceList() { return myFaceList; }
@@ -387,8 +393,8 @@ protected:
NCollection_IndexedMap<TCollection_AsciiString>*
myExternalFiles; //!< list of external file references
RWMesh_CoordinateSystemConverter myCSTrsf; //!< transformation from glTF to OCCT coordinate system
TColStd_IndexedDataMapOfStringString* myMetadata; //!< file metadata
TColStd_IndexedDataMapOfStringString myMetadata; //!< file metadata
NCollection_DataMap<TCollection_AsciiString, Handle(RWGltf_MaterialMetallicRoughness)> myMaterialsPbr;
NCollection_DataMap<TCollection_AsciiString, Handle(RWGltf_MaterialCommon)> myMaterialsCommon;
NCollection_DataMap<TCollection_AsciiString, TopoDS_Shape> myShapeMap[2];
@@ -405,6 +411,7 @@ protected:
bool myIsBinary; //!< binary document
bool myIsGltf1; //!< obsolete glTF 1.0 version format
bool myToSkipEmptyNodes; //!< ignore nodes without Geometry
bool myUseMeshNameAsFallback; //!< flag to use Mesh name in case if Node name is empty, TRUE by default
bool myToProbeHeader; //!< flag to probe header without full reading, FALSE by default
#ifdef HAVE_RAPIDJSON

View File

@@ -79,12 +79,15 @@ public:
//! Add primitive array data element.
Standard_EXPORT RWGltf_GltfPrimArrayData& AddPrimArrayData (RWGltf_GltfArrayType theType);
//! Return bounding box defined within glTF file, or VOID if not specified.
const Bnd_Box& BoundingBox() const { return myBox; }
//! This method sets input bounding box and assigns a FAKE data to underlying Poly_Triangulation
//! as Min/Max corners of bounding box, so that standard tools like BRepBndLib::Add()
//! can be used transparently for computing bounding box of this face.
Standard_EXPORT void SetBoundingBox (const Bnd_Box& theBox);
private:
protected:
NCollection_Sequence<RWGltf_GltfPrimArrayData> myData;
Handle(RWGltf_MaterialMetallicRoughness) myMaterialPbr; //!< PBR material

View File

@@ -90,13 +90,10 @@ Standard_Boolean RWMesh_CafReader::perform (const TCollection_AsciiString& theFi
const Standard_Boolean theToProbe)
{
Standard_Integer aNewRootsLower = 1;
Handle(XCAFDoc_ShapeTool) aShapeTool = !myXdeDoc.IsNull()
? XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main())
: Handle(XCAFDoc_ShapeTool)();
if (!myXdeDoc.IsNull())
{
TDF_LabelSequence aRootLabels;
aShapeTool->GetFreeShapes (aRootLabels);
XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main())->GetFreeShapes (aRootLabels);
aNewRootsLower = aRootLabels.Upper() + 1;
}
@@ -118,28 +115,11 @@ Standard_Boolean RWMesh_CafReader::perform (const TCollection_AsciiString& theFi
myExtraStatus |= RWMesh_CafReaderStatusEx_Partial;
}
BRep_Builder aBuilder;
TopoDS_Shape aShape;
if (myRootShapes.Size() > 1)
{
TopoDS_Compound aCompound;
aBuilder.MakeCompound (aCompound);
for (TopTools_SequenceOfShape::Iterator aRootIter (myRootShapes); aRootIter.More(); aRootIter.Next())
{
aBuilder.Add (aCompound, aRootIter.Value());
}
aShape = aCompound;
}
else if (!myRootShapes.IsEmpty())
{
aShape = myRootShapes.First();
}
TopLoc_Location aDummyLoc;
Standard_Integer aNbNodes = 0, aNbElems = 0, aNbFaces = 0;
if (!aShape.IsNull())
for (TopTools_SequenceOfShape::Iterator aRootIter (myRootShapes); aRootIter.More(); aRootIter.Next())
{
TopLoc_Location aDummyLoc;
for (TopExp_Explorer aFaceIter (aShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
for (TopExp_Explorer aFaceIter (aRootIter.Value(), TopAbs_FACE); aFaceIter.More(); aFaceIter.Next())
{
const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Current());
if (const Handle(Poly_Triangulation)& aPolyTri = BRep_Tool::Triangulation (aFace, aDummyLoc))
@@ -155,42 +135,41 @@ Standard_Boolean RWMesh_CafReader::perform (const TCollection_AsciiString& theFi
return Standard_False;
}
if (myToFillDoc
&& !myXdeDoc.IsNull())
{
const Standard_Boolean wasAutoNaming = aShapeTool->AutoNaming();
aShapeTool->SetAutoNaming (Standard_False);
const TCollection_AsciiString aRootName; // = generateRootName (theFile);
for (TopTools_SequenceOfShape::Iterator aRootIter (myRootShapes); aRootIter.More(); aRootIter.Next())
{
addShapeIntoDoc (aRootIter.Value(), TDF_Label(), aRootName);
}
aShapeTool->UpdateAssemblies();
aShapeTool->SetAutoNaming (wasAutoNaming);
}
if (!myXdeDoc.IsNull())
{
generateNames (theFile, aNewRootsLower, Standard_False);
}
fillDocument();
generateNames (theFile, aNewRootsLower, Standard_False);
aLoadingTimer.Stop();
TCollection_AsciiString aStats = TCollection_AsciiString("[") + aNbNodes + " nodes] [" + aNbElems + " 2d elements]";
if (!isDone)
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Mesh ") + theFile
+ "\n" + aStats
+ "\n[PARTIALLY read in " + aLoadingTimer.ElapsedTime() + " s]", Message_Info);
}
else
{
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Mesh ") + theFile
+ "\n" + aStats
+ "\n[read in " + aLoadingTimer.ElapsedTime() + " s]", Message_Info);
}
Message::DefaultMessenger()->Send (TCollection_AsciiString ("Mesh ") + theFile
+ "\n[" + aNbNodes + " nodes] [" + aNbElems + " 2d elements]"
+ "\n[" + (!isDone ? "PARTIALLY " : "") + "read in " + aLoadingTimer.ElapsedTime() + " s]", Message_Info);
return Standard_True;
}
// =======================================================================
// function : fillDocument
// purpose :
// =======================================================================
void RWMesh_CafReader::fillDocument()
{
if (!myToFillDoc
|| myXdeDoc.IsNull()
|| myRootShapes.IsEmpty())
{
return;
}
const Standard_Boolean wasAutoNaming = XCAFDoc_ShapeTool::AutoNaming();
XCAFDoc_ShapeTool::SetAutoNaming (Standard_False);
const TCollection_AsciiString aRootName; // = generateRootName (theFile);
for (TopTools_SequenceOfShape::Iterator aRootIter (myRootShapes); aRootIter.More(); aRootIter.Next())
{
addShapeIntoDoc (aRootIter.Value(), TDF_Label(), aRootName);
}
XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main())->UpdateAssemblies();
XCAFDoc_ShapeTool::SetAutoNaming (wasAutoNaming);
}
// =======================================================================
// function : addShapeIntoDoc
// purpose :
@@ -207,14 +186,11 @@ Standard_Boolean RWMesh_CafReader::addShapeIntoDoc (const TopoDS_Shape& theShape
Handle(XCAFDoc_ShapeTool) aShapeTool = XCAFDoc_DocumentTool::ShapeTool (myXdeDoc->Main());
TopLoc_Location aDummyLoc;
const TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
TopoDS_Shape aShapeToAdd = theShape;
Standard_Boolean toMakeAssembly = Standard_False;
if (theShape.ShapeType() == TopAbs_COMPOUND)
{
TCollection_AsciiString aFirstName;
RWMesh_NodeAttributes aSubFaceAttribs;
for (TopoDS_Iterator aSubShapeIter (theShape, Standard_True, Standard_False); !toMakeAssembly && aSubShapeIter.More(); aSubShapeIter.Next())
{
@@ -366,9 +342,7 @@ void RWMesh_CafReader::generateNames (const TCollection_AsciiString& theFile,
if (theWithSubLabels)
{
for (XCAFPrs_DocumentExplorer aDocIter (myXdeDoc,
aNewRootLabels,
XCAFPrs_DocumentExplorerFlags_OnlyLeafNodes | XCAFPrs_DocumentExplorerFlags_NoStyle);
for (XCAFPrs_DocumentExplorer aDocIter (myXdeDoc, aNewRootLabels, XCAFPrs_DocumentExplorerFlags_NoStyle);
aDocIter.More(); aDocIter.Next())
{
if (aDocIter.CurrentDepth() == 0

View File

@@ -173,18 +173,21 @@ protected:
//! @param theFile file to read
//! @param optional progress indicator
//! @param theToProbe flag indicating that mesh data should be skipped and only basing information to be read
virtual Standard_Boolean perform (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress,
const Standard_Boolean theToProbe);
Standard_EXPORT virtual Standard_Boolean perform (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress,
const Standard_Boolean theToProbe);
//! Read the mesh from specified file - interface to be implemented by sub-classes.
virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress,
const Standard_Boolean theToProbe) = 0;
Standard_EXPORT virtual Standard_Boolean performMesh (const TCollection_AsciiString& theFile,
const Handle(Message_ProgressIndicator)& theProgress,
const Standard_Boolean theToProbe) = 0;
//! @name tools for filling XDE document
protected:
//! Fill document with new root shapes.
Standard_EXPORT void fillDocument();
//! Append new shape into the document (recursively).
Standard_EXPORT Standard_Boolean addShapeIntoDoc (const TopoDS_Shape& theShape,
const TDF_Label& theLabel,

View File

@@ -63,7 +63,18 @@ namespace
theRelativePath = aRelPath;
return true;
}
aPath = aFolder;
for (; aPath.Length() >= 2;)
{
if (aPath.Value (aPath.Length()) == '/'
|| aPath.Value (aPath.Length()) == '\\')
{
aPath = aPath.SubString (1, aPath.Length() - 1);
continue;
}
break;
}
}
}
}
@@ -195,6 +206,7 @@ bool RWObj_MtlReader::Read (const TCollection_AsciiString& theFolder,
if (validateColor (aColor))
{
aMat.SpecularColor = Quantity_Color (aColor.r(), aColor.g(), aColor.b(), Quantity_TOC_RGB);
hasAspect = true;
}
}
else if (::memcmp (aPos, "Ns", 2) == 0
@@ -207,6 +219,7 @@ bool RWObj_MtlReader::Read (const TCollection_AsciiString& theFolder,
if (aSpecular >= 0.0)
{
aMat.Shininess = (float )Min (aSpecular / 1000.0, 1.0);
hasAspect = true;
}
}
else if (::memcmp (aPos, "Tr", 2) == 0
@@ -220,6 +233,7 @@ bool RWObj_MtlReader::Read (const TCollection_AsciiString& theFolder,
&& aTransp <= 0.99)
{
aMat.Transparency = (float )aTransp;
hasAspect = true;
}
}
else if (*aPos == 'd' && IsSpace (aPos[1]))
@@ -233,6 +247,7 @@ bool RWObj_MtlReader::Read (const TCollection_AsciiString& theFolder,
&& anAlpha >= 0.01)
{
aMat.Transparency = float(1.0 - anAlpha);
hasAspect = true;
}
}
else if (::memcmp (aPos, "map_Kd", 6) == 0
@@ -242,6 +257,7 @@ bool RWObj_MtlReader::Read (const TCollection_AsciiString& theFolder,
if (RWObj_Tools::ReadName (aPos, aMat.DiffuseTexture))
{
processTexturePath (aMat.DiffuseTexture, theFolder);
hasAspect = true;
}
}
else if (::memcmp (aPos, "map_Ks", 6) == 0
@@ -251,6 +267,7 @@ bool RWObj_MtlReader::Read (const TCollection_AsciiString& theFolder,
if (RWObj_Tools::ReadName (aPos, aMat.SpecularTexture))
{
processTexturePath (aMat.SpecularTexture, theFolder);
hasAspect = true;
}
}
else if (::memcmp (aPos, "map_Bump", 8) == 0
@@ -260,6 +277,7 @@ bool RWObj_MtlReader::Read (const TCollection_AsciiString& theFolder,
if (RWObj_Tools::ReadName (aPos, aMat.BumpTexture))
{
processTexturePath (aMat.BumpTexture, theFolder);
hasAspect = true;
}
}
/*else if (::memcmp (aPos, "illum", 5) == 0)

View File

@@ -32,7 +32,6 @@ Standard_Boolean RWObj_TriangulationReader::addMesh (const RWObj_SubMesh& theMes
return Standard_False;
}
const RWObj_Material* aMaterial = myMaterials.Seek (theMesh.Material);
if (Handle(Poly_Triangulation) aTris = GetTriangulation())
{
myNodes.Clear();
@@ -46,7 +45,11 @@ Standard_Boolean RWObj_TriangulationReader::addMesh (const RWObj_SubMesh& theMes
{
if (myShapeReceiver != NULL)
{
myShapeReceiver->BindNamedShape (myLastGroupShape, theMesh.Group, myLastGroupShape.ShapeType() == TopAbs_FACE ? aMaterial : NULL, Standard_False);
const RWObj_Material* aMaterial = myLastGroupShape.ShapeType() == TopAbs_FACE
&& !myLastFaceMaterial.IsEmpty()
? myMaterials.Seek (myLastFaceMaterial)
: NULL;
myShapeReceiver->BindNamedShape (myLastGroupShape, myLastGroupName, aMaterial, Standard_False);
}
}
myLastGroupShape = TopoDS_Shape();
@@ -57,8 +60,10 @@ Standard_Boolean RWObj_TriangulationReader::addMesh (const RWObj_SubMesh& theMes
BRep_Builder aBuilder;
aBuilder.MakeFace (aNewFace, aTris);
addSubShape (myLastGroupShape, aNewFace, Standard_True);
myLastFaceMaterial = theMesh.Material;
if (myShapeReceiver != NULL)
{
const RWObj_Material* aMaterial = myMaterials.Seek (theMesh.Material);
myShapeReceiver->BindNamedShape (aNewFace, "", aMaterial, Standard_False);
}
}
@@ -70,7 +75,11 @@ Standard_Boolean RWObj_TriangulationReader::addMesh (const RWObj_SubMesh& theMes
{
if (myShapeReceiver != NULL)
{
myShapeReceiver->BindNamedShape (myLastGroupShape, theMesh.Group, myLastGroupShape.ShapeType() == TopAbs_FACE ? aMaterial : NULL, Standard_False);
const RWObj_Material* aMaterial = myLastGroupShape.ShapeType() == TopAbs_FACE
&& !myLastFaceMaterial.IsEmpty()
? myMaterials.Seek (myLastFaceMaterial)
: NULL;
myShapeReceiver->BindNamedShape (myLastGroupShape, myLastGroupName, aMaterial, Standard_False);
}
}
myLastGroupShape = TopoDS_Shape();

View File

@@ -117,6 +117,7 @@ protected:
TopoDS_Compound myLastObjectShape; //!< Compound containing current object groups
TopoDS_Shape myLastGroupShape; //!< current group shape - either a single Face or Compound of Faces
TCollection_AsciiString myLastGroupName; //!< current group name
TCollection_AsciiString myLastFaceMaterial;//!< last face material name
Standard_Boolean myToCreateShapes; //!< create a single triangulation
};

View File

@@ -443,6 +443,15 @@ void StdSelect_BRepSelectionTool::GetEdgeSensitive (const TopoDS_Shape& theShape
Handle(Select3D_SensitiveEntity)& theSensitive)
{
const TopoDS_Edge& anEdge = TopoDS::Edge (theShape);
// try to get points from existing polygons
Handle(TColgp_HArray1OfPnt) aPoints = GetPointsFromPolygon (anEdge);
if (!aPoints.IsNull()
&& !aPoints->IsEmpty())
{
theSensitive = new Select3D_SensitiveCurve (theOwner, aPoints);
return;
}
BRepAdaptor_Curve cu3d;
try {
OCC_CATCH_SIGNALS
@@ -451,14 +460,6 @@ void StdSelect_BRepSelectionTool::GetEdgeSensitive (const TopoDS_Shape& theShape
return;
}
// try to get points from existing polygons
Handle(TColgp_HArray1OfPnt) aPoints = GetPointsFromPolygon (anEdge);
if (!aPoints.IsNull() && aPoints->Length() > 0)
{
theSensitive = new Select3D_SensitiveCurve (theOwner, aPoints);
return;
}
Standard_Real aParamFirst = cu3d.FirstParameter();
Standard_Real aParamLast = cu3d.LastParameter();
switch (cu3d.GetType())

View File

@@ -3344,6 +3344,10 @@ public:
virtual Standard_Boolean AcceptDisplayMode (const Standard_Integer theMode) const Standard_OVERRIDE { return theMode == 0; }
//! Sets color to this interactive object
//! @param theColor the color to be set
virtual void SetColor (const Quantity_Color& theColor) Standard_OVERRIDE;
private:
void Compute (const Handle(PrsMgr_PresentationManager3d)& aPresentationManager,
@@ -3359,6 +3363,13 @@ private:
Standard_Integer theArgCount,
Standard_Integer theMaxArgs);
//! Sets color for the shading aspect of the drawer used in this interactive object
//! @param theColor the color to be set
void setColorForShadingAspect(const Quantity_Color& theColor);
//! Replaces shading aspect from myDrawer->Link() with the own shading aspect of myDrawer for this interactive object
void replaceShadingAspect();
protected:
Handle(Graphic3d_AspectMarker3d) myMarkerAspect;
@@ -3584,6 +3595,21 @@ Standard_Boolean MyPArrayObject::Init (Graphic3d_TypeOfPrimitiveArray thePrimTyp
return Standard_True;
}
//=======================================================================
// function : SetColor
// purpose :
//=======================================================================
void MyPArrayObject::SetColor (const Quantity_Color& theColor)
{
AIS_InteractiveObject::SetColor (theColor);
setColorForShadingAspect (theColor);
if (myMarkerAspect)
{
myMarkerAspect->SetColor (theColor);
}
SynchronizeAspects();
}
void MyPArrayObject::ComputeSelection (const Handle(SelectMgr_Selection)& theSelection,
const Standard_Integer theMode)
{
@@ -3660,6 +3686,34 @@ bool MyPArrayObject::CheckInputCommand (const TCollection_AsciiString theCommand
return true;
}
//=======================================================================
// function : setColorForShadingAspect
// purpose :
//=======================================================================
void MyPArrayObject::setColorForShadingAspect (const Quantity_Color& theColor)
{
if (myDrawer->SetupOwnShadingAspect())
{
replaceShadingAspect();
}
myDrawer->ShadingAspect()->SetColor (theColor);
}
//=======================================================================
// function : replaceShadingAspect
// purpose :
//=======================================================================
void MyPArrayObject::replaceShadingAspect()
{
if (!myDrawer->Link())
{
return;
}
Graphic3d_MapOfAspectsToAspects anAspectReplacementMap;
anAspectReplacementMap.Bind (myDrawer->Link()->ShadingAspect()->Aspect(), myDrawer->ShadingAspect()->Aspect());
replaceAspects (anAspectReplacementMap);
}
//=============================================================================
//function : VDrawPArray
//purpose : Draws primitives array from list of vertexes, bounds, edges
@@ -4717,6 +4771,46 @@ static Standard_Integer VChild (Draw_Interpretor& ,
return 0;
}
//=======================================================================
//function : VParent
//purpose :
//=======================================================================
static Standard_Integer VParent(Draw_Interpretor&,
Standard_Integer theNbArgs,
const char** theArgVec)
{
Handle(AIS_InteractiveContext) aContext = ViewerTest::GetAISContext();
if (aContext.IsNull())
{
std::cout << "Error: no active view\n";
return 1;
}
if (theNbArgs < 2 )
{
std::cout << theArgVec[0] << " error: expect at least 2 arguments\n";
return 1;
}
TCollection_AsciiString aName(theArgVec[1]);
Handle(AIS_InteractiveObject) aParent;
if (!GetMapOfAIS().Find2(theArgVec[1], aParent))
{
std::cout << "Syntax error: object '" << theArgVec[1] << "' is not found\n";
return 1;
}
ViewerTest_AutoUpdater anUpdateTool(aContext, ViewerTest::CurrentView());
for (Standard_Integer anArgIter = 2; anArgIter < theNbArgs; ++anArgIter)
{
TCollection_AsciiString anArg(theArgVec[anArgIter]);
anArg.LowerCase();
if (anArg == "-ignorevisu")
aParent->SetPropagateVisualState(Standard_False);
}
return 0;
}
//===============================================================================================
//function : VSetSelectionMode
//purpose : vselmode
@@ -6454,6 +6548,12 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands)
"\n\t\t: Command for testing low-level presentation connections."
"\n\t\t: vconnect command should be used instead.",
__FILE__, VChild, group);
theCommands.Add("vparent",
"vparent parent [-ignoreVisu]"
"\n\t\t: Command for testing object properties as parent in the hierarchy."
"\n\t\t: Arguments:"
"\n\t\t: -ignoreVisu do not propagate the visual state (display/erase/color) to children objects",
__FILE__, VParent, group);
theCommands.Add ("vcomputehlr",
"vcomputehlr shapeInput hlrResult [-algoType {algo|polyAlgo}=polyAlgo]"
"\n\t\t: [eyeX eyeY eyeZ dirX dirY dirZ upX upY upZ]"

View File

@@ -12280,10 +12280,10 @@ static int VManipulator (Draw_Interpretor& theDi,
Standard_Integer theArgsNb,
const char** theArgVec)
{
Handle(V3d_View) aView = ViewerTest::CurrentView();
Handle(V3d_View) aCurrentView = ViewerTest::CurrentView();
Handle(V3d_Viewer) aViewer = ViewerTest::GetViewerFromContext();
ViewerTest::GetAISContext()->MainSelector()->SetPickClosest (Standard_False);
if (aView.IsNull()
if (aCurrentView.IsNull()
|| aViewer.IsNull())
{
std::cerr << "No active viewer!\n";
@@ -12303,6 +12303,7 @@ static int VManipulator (Draw_Interpretor& theDi,
aCmd.AddOption ("adjustPosition", "... {0|1} - adjust position when attaching");
aCmd.AddOption ("adjustSize", "... {0|1} - adjust size when attaching ");
aCmd.AddOption ("enableModes", "... {0|1} - enable modes when attaching ");
aCmd.AddOption ("view", "... {active | [view name]} - define view in which manipulator will be displayed, 'all' by default");
aCmd.AddOption ("detach", "... - detach manipulator");
aCmd.AddOption ("startTransform", "... mouse_x mouse_y - invoke start transformation");
@@ -12508,6 +12509,42 @@ static int VManipulator (Draw_Interpretor& theDi,
}
aManipulator->Attach (anObject, anOptions);
// Check view option
if (aCmd.HasOption ("view"))
{
if (!aCmd.HasOption ("view", 1, Standard_True))
{
return 1;
}
TCollection_AsciiString aViewString (aCmd.Arg ("view", 0).c_str());
Handle(V3d_View) aView;
if (aViewString.IsEqual ("active"))
{
aView = ViewerTest::CurrentView();
}
else // Check view name
{
ViewerTest_Names aViewNames (aViewString);
if (!ViewerTest_myViews.IsBound1 (aViewNames.GetViewName()))
{
std::cerr << theArgVec[0] << " error: wrong view name '" << aViewString << "'\n";
return 1;
}
aView = ViewerTest_myViews.Find1 (aViewNames.GetViewName());
if (aView.IsNull())
{
std::cerr << theArgVec[0] << " error: cannot find view with name '" << aViewString << "'\n";
return 1;
}
}
for (NCollection_DoubleMap <TCollection_AsciiString, Handle(V3d_View)>::Iterator
anIter (ViewerTest_myViews); anIter.More(); anIter.Next())
{
ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, anIter.Value(), Standard_False);
}
ViewerTest::GetAISContext()->SetViewAffinity (aManipulator, aView, Standard_True);
}
}
// --------------------------------------
@@ -13756,6 +13793,8 @@ void ViewerTest::ViewerCommands(Draw_Interpretor& theCommands)
"\n '-adjustPosition {0|1}' adjust position when attaching"
"\n '-adjustSize {0|1}' adjust size when attaching"
"\n '-enableModes {0|1}' enable modes when attaching"
"\n '-view {active | [name of view]}' display manipulator only in defined view,"
"\n by default it is displayed in all views of the current viewer"
"\n '-detach' detach manipulator"
"\n '-startTransform mouse_x mouse_y' - invoke start of transformation"
"\n '-transform mouse_x mouse_y' - invoke transformation"

View File

@@ -0,0 +1,12 @@
puts "============"
puts "0030804: Foundation Classes - Poly_Connect crashes due to out-of-range array modification"
puts "============"
pload MODELING VISUALIZATION
restore [locate_data_file bug30804.brep] b
vclear
vinit View1
vdisplay b
vfit
vdump ${imagedir}/${casename}.png

View File

@@ -0,0 +1,19 @@
puts "========="
puts "0025807: Bad performance of meshing"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file shape_506819_1.brep] result
tclean result
incmesh result 0.001
checktrinfo result -tri 25314 -nod 59186 -defl 0.0010000000000000007
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,19 @@
puts "========="
puts "0025807: Bad performance of meshing"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file shape_778972_1.brep] result
tclean result
incmesh result 0.001
checktrinfo result -tri 19974 -nod 46036 -defl 0.0010000000000000007
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,19 @@
puts "========="
puts "0025807: Bad performance of meshing"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file shape_894944_1.brep] result
tclean result
incmesh result 0.001
checktrinfo result -tri 26774 -nod 62436 -defl 0.0010000000000000007
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,19 @@
puts "========="
puts "0025807: Bad performance of meshing"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file shape_1174827_1.brep] result
tclean result
incmesh result 0.001
checktrinfo result -tri 25314 -nod 59186 -defl 0.0010000000000000007
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

19
tests/bugs/mesh/bug26074 Normal file
View File

@@ -0,0 +1,19 @@
puts "========="
puts "0026074: BRepMesh_IncrementalMesh meshes a specific shape for a long time"
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file bug26074.brep] result
tclean result
incmesh result 0.01116 -a 15 -parallel
checktrinfo result -tri
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

19
tests/bugs/mesh/bug29506 Normal file
View File

@@ -0,0 +1,19 @@
puts "========="
puts "0029506: DRAW command 'incmesh' hangs on the attached planar face with specified deflection."
puts "========="
puts ""
set ::env(CSF_MeshAlgo) 1
restore [locate_data_file bug29506.brep] result
tclean result
incmesh result 1e-6
checktrinfo result -tri 44437 -nod 44437 -defl 9.9999999999999995e-07
vinit
vsetdispmode 1
vdefaults -autoTriang 0
vdisplay result
vfit
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

18
tests/bugs/mesh/bug30780 Normal file
View File

@@ -0,0 +1,18 @@
puts "========="
puts "0030780: BRepMesh fails triangulating one face of the shape"
puts "========="
puts ""
binrestore [locate_data_file bug30780_full.bin] result
tclean result
incmesh result 7.066 -a 20 -adjust_min
checktrinfo result -tri
set log [tricheck result]
if { [llength $log] != 0 } {
puts "Error : Invalid mesh"
} else {
puts "Mesh is OK"
}

View File

@@ -0,0 +1,21 @@
puts "TODO OCC30808 ALL: \\*\\* Exception \\*\\*.*"
puts "TODO OCC30808 ALL: An exception was caught"
puts "TODO OCC30808 ALL:TEST INCOMPLETE"
puts "========"
puts "0030787: BRepOffsetAPI_MakePipeShell: hangs on the attached model"
puts "========"
puts ""
cpulimit 300
circle profile 0 -1.81898940354586e-12 0 0 -0.999995598293478 -0.00296705134258169 1 0 0 25
mkedge profile profile
wire profile profile
restore [locate_data_file bug30787_spine.brep] path
mksweep path
addsweep profile
buildsweep result -C -S

View File

@@ -1,5 +1,5 @@
puts "========"
puts "0030794: BRepOffsetAPI_MakePipeShell: shape is produced with artifacts"
puts "0030817: Modeling Algorithms - BRepOffsetAPI_MakePipeShell produces invalid result"
puts "========"
puts ""

25
tests/bugs/vis/bug30823 Normal file
View File

@@ -0,0 +1,25 @@
puts "============="
puts "0030823: Visualization, PrsMgr_PresentableObject - A new flag to disable automatic display/erase of children"
puts "============="
pload MODELING VISUALIZATION
vclear
vinit View1
psphere parent 3
vdisplay -dispMode 1 parent
box child1 1 1 1
box child2 1 1 1
vdisplay child1 -dispMode 1
vdisplay child2 -dispMode 1
vlocation child1 -setLocation 10 0 0
vlocation child2 -setLocation 20 0 0
vparent parent -ignoreVisu
vchild parent -ignoreParentTrsf -add child1
vchild parent -ignoreParentTrsf -add child2
vfit
verase parent
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

25
tests/bugs/vis/bug30824 Normal file
View File

@@ -0,0 +1,25 @@
puts "============="
puts "0030824: Visualization, PrsMgr_PresentableObject - A new flag to disable automatic selection of children"
puts "============="
pload MODELING VISUALIZATION
vclear
vinit View1
psphere parent 3
vdisplay -dispMode 1 parent
box child1 1 1 1
box child2 1 1 1
vdisplay child1 -dispMode 1
vdisplay child2 -dispMode 1
vlocation child1 -setLocation 10 0 0
vlocation child2 -setLocation 20 0 0
vparent parent -ignoreVisu
vchild parent -ignoreParentTrsf -add child1
vchild parent -ignoreParentTrsf -add child2
vfit
vselect 0 0 200 200
checkview -screenshot -3d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
puts "================"
puts "0029679: Command 2dapprox works wrong when giving points in command line"
puts "================"
puts ""
2dapprox c 5 0 0 3 4 -1 4 -4 0 -4 -3
checklength c -l 18.723980878126035
smallview -2D-
2dfit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -0,0 +1,12 @@
puts "================"
puts "0029679: Command 2dapprox works wrong when giving points in command line"
puts "================"
puts ""
2dinterpole c 5 0 0 3 4 -1 4 -4 0 -4 -3
checklength c -l 18.236785351873756
smallview -2D-
2dfit
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -30,7 +30,7 @@ if { $int1 == 0 || $int2 == 0 || $int3 == 0 || $int4 ==0 } {
puts "Error : Intersection is not found"
}
av2d
smallview -2D-
2dfit
xwd ${imagedir}/${test_image}.png

View File

@@ -16,7 +16,7 @@ if { ${int1} == 0 } {
puts "Error : Intersection is not found"
}
av2d
smallview -2D-
2dfit
xwd ${imagedir}/${test_image}.png

View File

@@ -6,17 +6,16 @@ puts ""
# Incorrect result of intersection in 2D between circle and line
#######################################################################################
v2d2
smallview -2D-
don
circle c1 2 2 1
2dfit
2dzoom 120
line l1 3 0 0 1
2dintersect l1 c1
erase l1 c1
2dfit
puts "ATTENTION! Check following:"
puts "There is only one intersection point (green X)"
checkview -display result -2d -path ${imagedir}/${test_image}.png
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -6,7 +6,7 @@ puts ""
# Incorrect result of intersection in 2D between circle and line
#######################################################################################
v2d2
smallview -2D-
line ll1 0 0 0.3 0.7
line ll2 0 0 0.37 0.63
trim tll1 ll1 -0.00001 0.00001
@@ -18,5 +18,4 @@ donly tll1 tll2
puts "ATTENTION! Check following:"
puts "There is the intersection point (green X) on center of grid axis"
checkview -display result -2d -path ${imagedir}/${test_image}.png
checkview -screenshot -2d -path ${imagedir}/${test_image}.png

View File

@@ -1,8 +1,9 @@
001 2dinter
002 bnd
003 extcs
004 extcc
005 2dgcc
006 intss
007 classifier
008 bvh
001 2dapprox
002 2dinter
003 bnd
004 extcs
005 extcc
006 2dgcc
007 intss
008 classifier
009 bvh

View File

@@ -0,0 +1,30 @@
puts "====================================="
puts "Display manipulator in one view only"
puts "====================================="
pload MODELING VISUALIZATION
vclear
vclose ALL
vinit View1
vinit View2
vaxo
box b 500 500 1 50 100 150
vdisplay b -dispMode 1
vfit
vactivate View1
vmanipulator m -attach b -view active
vfit
vmoveto 200 200
vdump $imagedir/${casename}_View1_1.png
vactivate View2
vdump $imagedir/${casename}_View2_1.png
vmanipulator m -detach
vmanipulator m -attach b -view View2
vmoveto 200 200
vdump $imagedir/${casename}_View2_2.png
vactivate View1
vdump $imagedir/${casename}_View1_2.png
vmanipulator m -detach