Skip to content
Snippets Groups Projects
Commit 12e96b58 authored by Christophe Geuzaine's avatar Christophe Geuzaine
Browse files

prepare OCC transforms

parent 65bcdbf7
No related branches found
No related tags found
No related merge requests found
......@@ -35,10 +35,11 @@
#include <Geom_Circle.hxx>
#include <Geom_TrimmedCurve.hxx>
int OCC_Internals::_getMaxTag(int dim) const
int OCC_Internals::getMaxTag(int dim) const
{
if(dim < 0 || dim > 3) return 0;
TopTools_DataMapIteratorOfDataMapOfIntegerShape exp;
int ret = 0;
int ret = _maxTagConstraints[dim];
switch(dim){
case 0: exp.Initialize(_tagVertex); break;
case 1: exp.Initialize(_tagEdge); break;
......@@ -67,7 +68,7 @@ void OCC_Internals::addVertex(int tag, double x, double y, double z)
Msg::Error("OCC %s", err.GetMessageString());
return;
}
if(tag <= 0) tag = _getMaxTag(0) + 1;
if(tag <= 0) tag = getMaxTag(0) + 1;
bind(result, tag);
}
......@@ -96,7 +97,7 @@ void OCC_Internals::addLine(int tag, int startTag, int endTag)
Msg::Error("OCC %s", err.GetMessageString());
return;
}
if(tag <= 0) tag = _getMaxTag(1) + 1;
if(tag <= 0) tag = getMaxTag(1) + 1;
bind(result, tag);
}
......@@ -140,7 +141,7 @@ void OCC_Internals::addCircleArc(int tag, int startTag, int centerTag, int endTa
Msg::Error("OCC %s", err.GetMessageString());
return;
}
if(tag <= 0) tag = _getMaxTag(1) + 1;
if(tag <= 0) tag = getMaxTag(1) + 1;
bind(result, tag);
}
......@@ -160,7 +161,7 @@ void OCC_Internals::addSphere(int tag, double xc, double yc, double zc, double r
Msg::Error("OCC %s", err.GetMessageString());
return;
}
if(tag <= 0) tag = _getMaxTag(3) + 1;
if(tag <= 0) tag = getMaxTag(3) + 1;
bind(result, tag);
}
......@@ -183,7 +184,7 @@ void OCC_Internals::addBlock(int tag, double x1, double y1, double z1,
Msg::Error("OCC %s", err.GetMessageString());
return;
}
if(tag <= 0) tag = _getMaxTag(3) + 1;
if(tag <= 0) tag = getMaxTag(3) + 1;
bind(result, tag);
}
......@@ -209,7 +210,7 @@ void OCC_Internals::addCylinder(int tag, double x1, double y1, double z1,
Msg::Error("OCC %s", err.GetMessageString());
return;
}
if(tag <= 0) tag = _getMaxTag(3) + 1;
if(tag <= 0) tag = getMaxTag(3) + 1;
bind(result, tag);
}
......@@ -243,7 +244,7 @@ void OCC_Internals::addThruSections(int tag, std::vector<std::vector<int> > edge
Msg::Error("OCC %s", err.GetMessageString());
return;
}
if(tag <= 0) tag = _getMaxTag(3) + 1;
if(tag <= 0) tag = getMaxTag(3) + 1;
bind(result, tag);
}
......@@ -458,7 +459,7 @@ std::vector<int> OCC_Internals::applyBooleanOperator(int tag,
bool first = true;
for(exp0.Init(result, TopAbs_SOLID); exp0.More(); exp0.Next()){
if(tag <= 0){
int t = _getMaxTag(3) + 1;
int t = getMaxTag(3) + 1;
bind(TopoDS::Solid(exp0.Current()), t);
out.push_back(t);
}
......@@ -491,17 +492,20 @@ void OCC_Internals::_addShapeToMaps(TopoDS_Shape shape)
if(_fmap.FindIndex(face) < 1){
_fmap.Add(face);
for(exp3.Init(exp2.Current().Oriented(TopAbs_FORWARD), TopAbs_WIRE); exp3.More(); exp3.Next()){
for(exp3.Init(exp2.Current().Oriented(TopAbs_FORWARD), TopAbs_WIRE);
exp3.More(); exp3.Next()){
TopoDS_Wire wire = TopoDS::Wire(exp3.Current());
if(_wmap.FindIndex(wire) < 1){
_wmap.Add(wire);
for(exp4.Init(exp3.Current(), TopAbs_EDGE); exp4.More(); exp4.Next()){
for(exp4.Init(exp3.Current(), TopAbs_EDGE); exp4.More();
exp4.Next()){
TopoDS_Edge edge = TopoDS::Edge(exp4.Current());
if(_emap.FindIndex(edge) < 1){
_emap.Add(edge);
for(exp5.Init(exp4.Current(), TopAbs_VERTEX); exp5.More(); exp5.Next()){
for(exp5.Init(exp4.Current(), TopAbs_VERTEX); exp5.More();
exp5.Next()){
TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current());
if(_vmap.FindIndex(vertex) < 1)
_vmap.Add(vertex);
......@@ -538,7 +542,8 @@ void OCC_Internals::_addShapeToMaps(TopoDS_Shape shape)
if(_emap.FindIndex(edge) < 1){
_emap.Add(edge);
for(exp5.Init(exp4.Current(), TopAbs_VERTEX); exp5.More(); exp5.Next()){
for(exp5.Init(exp4.Current(), TopAbs_VERTEX); exp5.More();
exp5.Next()){
TopoDS_Vertex vertex = TopoDS::Vertex(exp5.Current());
if(_vmap.FindIndex(vertex) < 1)
_vmap.Add(vertex);
......@@ -626,10 +631,10 @@ void OCC_Internals::_addShapeToMaps(TopoDS_Shape shape)
void OCC_Internals::importOCCInternals(GModel *model)
{
int vTagMax = std::max(model->getMaxElementaryNumber(0), _getMaxTag(0));
int eTagMax = std::max(model->getMaxElementaryNumber(1), _getMaxTag(1));
int fTagMax = std::max(model->getMaxElementaryNumber(2), _getMaxTag(2));
int rTagMax = std::max(model->getMaxElementaryNumber(3), _getMaxTag(3));
int vTagMax = std::max(model->getMaxElementaryNumber(0), getMaxTag(0));
int eTagMax = std::max(model->getMaxElementaryNumber(1), getMaxTag(1));
int fTagMax = std::max(model->getMaxElementaryNumber(2), getMaxTag(2));
int rTagMax = std::max(model->getMaxElementaryNumber(3), getMaxTag(3));
_somap.Clear();
_shmap.Clear();
......
......@@ -16,31 +16,45 @@
class OCC_Internals {
public:
enum BooleanOperator { Union, Intersection, Difference, Section, Fragments };
protected :
// a temporary shape
// FIXME will be removed
TopoDS_Shape _shape;
private :
// tag contraints coming from outside OCC_Internals (when using multiple CAD
// kernels)
int _maxTagConstraints[4];
protected :
// all the (sub)shapes, updated dynamically when shapes need to be imported
// into a GModel
TopTools_IndexedMapOfShape _vmap, _emap, _wmap, _fmap, _shmap, _somap;
// cache mapping TopoDS_Shapes to their corresponding GEntity tags
// cache mapping TopoDS_Shapes to their corresponding (future) GEntity tags
TopTools_DataMapOfShapeInteger _vertexTag, _edgeTag, _faceTag, _solidTag;
TopTools_DataMapOfIntegerShape _tagVertex, _tagEdge, _tagFace, _tagSolid;
// get maximum tag number for each dimension
int _getMaxTag(int dim) const;
// add a shape and all its subshapes to _vmap, _emap, ..., _somap
void _addShapeToMaps(TopoDS_Shape shape);
protected :
// FIXME will be removed
TopoDS_Shape _shape;
public:
// FIXME: will be removed with GModelFactory
void _addShapeToLists(TopoDS_Shape shape){ _addShapeToMaps(shape); }
public:
OCC_Internals() {}
OCC_Internals()
{
for(int i = 0; i < 4; i++) _maxTagConstraints[i] = 0;
}
// set constraints on tags
void setTagConstraints(int maxTags[4])
{
for(int i = 0; i < 4; i++) _maxTagConstraints[i] = maxTags[i];
}
// get maximum tag number for each dimension
int getMaxTag(int dim) const;
// add shapes only using internal OCC data
void addVertex(int tag, double x, double y, double z);
......@@ -147,6 +161,8 @@ class OCC_Internals {
public:
enum BooleanOperator { Union, Intersection, Difference, Section, Fragments };
OCC_Internals(){}
void setTagConstraints(int maxTags[4]){}
int getMaxTag(int dim) const { return 0; }
void addVertex(int tag, double x, double y, double z){}
void addLine(int tag, int startTag, int endTag){}
void addCircleArc(int tag, int tagStart, int tagCenter, int tagEnd){}
......
This diff is collapsed.
......@@ -1716,6 +1716,8 @@ Shape :
tSetFactory '(' StringExprVar ')' tEND
{
// FIXME: when changing to OpenCASCADE, get maxTag for all dimensions
// and add that info in OCC_Internals - same in the other direction
factory = $3;
Free($3);
}
......@@ -2552,27 +2554,52 @@ Shape :
Transform :
tTranslate VExpr '{' MultipleShape '}'
{
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
Msg::Error("TODO OCC Translate");
}
else{
TranslateShapes($2[0], $2[1], $2[2], $4);
}
$$ = $4;
}
| tRotate '{' VExpr ',' VExpr ',' FExpr '}' '{' MultipleShape '}'
{
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
Msg::Error("TODO OCC Rotate");
}
else{
RotateShapes($3[0], $3[1], $3[2], $5[0], $5[1], $5[2], $7, $10);
}
$$ = $10;
}
| tSymmetry VExpr '{' MultipleShape '}'
{
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
Msg::Error("TODO OCC Symmetry");
}
else{
SymmetryShapes($2[0], $2[1], $2[2], $2[3], $4);
}
$$ = $4;
}
| tDilate '{' VExpr ',' FExpr '}' '{' MultipleShape '}'
{
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
Msg::Error("TODO OCC Dilate");
}
else{
DilatShapes($3[0], $3[1], $3[2], $5, $5, $5, $8);
}
$$ = $8;
}
| tDilate '{' VExpr ',' VExpr '}' '{' MultipleShape '}'
{
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
Msg::Error("TODO OCC Dilate");
}
else{
DilatShapes($3[0], $3[1], $3[2], $5[0], $5[1], $5[2], $8);
}
$$ = $8;
}
| tSTRING '{' MultipleShape '}'
......@@ -2582,16 +2609,31 @@ Transform :
for(int i = 0; i < List_Nbr($3); i++){
Shape TheShape;
List_Read($3, i, &TheShape);
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
Msg::Error("TODO OCC Copy");
}
else{
CopyShape(TheShape.Type, TheShape.Num, &TheShape.Num);
}
List_Add($$, &TheShape);
}
}
else if(!strcmp($1, "Boundary")){
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
Msg::Error("TODO OCC Boundary");
}
else{
BoundaryShapes($3, $$, false);
}
}
else if(!strcmp($1, "CombinedBoundary")){
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
Msg::Error("TODO OCC Combined Boundary");
}
else{
BoundaryShapes($3, $$, true);
}
}
else{
yymsg(0, "Unknown command on multiple shapes: '%s'", $1);
}
......@@ -2601,17 +2643,27 @@ Transform :
| tIntersect tLine '{' RecursiveListOfDouble '}' tSurface '{' FExpr '}'
{
$$ = List_Create(2, 1, sizeof(Shape));
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
yymsg(0, "Intersect Line not available with OpenCASCADE");
}
else{
IntersectCurvesWithSurface($4, (int)$8, $$);
}
List_Delete($4);
}
| tSplit tLine '(' FExpr ')' '{' RecursiveListOfDouble '}' tEND
{
$$ = List_Create(2, 1, sizeof(Shape*));
if(factory == "OpenCASCADE" && GModel::current()->getOCCInternals()){
yymsg(0, "Split Line not available with OpenCASCADE");
}
else{
List_T *tmp = ListOfDouble2ListOfInt($7);
List_Delete($7);
SplitCurve((int)$4, tmp, $$);
List_Delete(tmp);
}
List_Delete($7);
}
;
MultipleShape :
......
......@@ -5,18 +5,27 @@ Mesh.CharacteristicLengthMin = 0.1;
Mesh.CharacteristicLengthMax = 0.1;
DefineConstant[
sph = {0, Choices{0,1}, Name "Make sphere a single volume"}
xx = {2.2, Min -1, Max 5, Step 0.01, Name "Sphere position"}
rr = {0.5, Min 0.1, Max 3, Step 0.01, Name "Sphere radius"}
x = {0, Min 0.1, Max 3, Step 0.01, Name "Bloc 1/0x"}
y = {0, Min 0.1, Max 3, Step 0.01, Name "Bloc 1/0y"}
z = {0, Min 0.1, Max 3, Step 0.01, Name "Bloc 1/0z"}
dx = {2, Min 0.1, Max 3, Step 0.01, Name "Bloc 1/dx"}
dy = {2, Min 0.1, Max 3, Step 0.01, Name "Bloc 1/dy"}
dz = {2, Min 0.1, Max 3, Step 0.01, Name "Bloc 1/dz"}
x2 = {x+dx, Min 0.1, Max 3, Step 0.01, Name "Bloc 2/0x"}
y2 = {0, Min 0.1, Max 3, Step 0.01, Name "Bloc 2/0y"}
z2 = {0, Min 0.1, Max 3, Step 0.01, Name "Bloc 2/0z"}
dx2 = {1, Min 0.1, Max 3, Step 0.01, Name "Bloc 2/dx"}
dy2 = {1, Min 0.1, Max 3, Step 0.01, Name "Bloc 2/dy"}
dz2 = {3, Min 0.1, Max 3, Step 0.01, Name "Bloc 2/dz"}
];
Block(1) = {x,y,z, x+dx,y+dy,z+dz};
Block(2) = {x2,y2,z2, x2+dx2,y2+dy2,z2+dz2};
Block(1) = {0,0,0, 2,2,2};
Sphere(2) = {xx, 1, 1, rr};
Block(3) = {2,0,0, 4,2,2};
f() = BooleanFragments { Volume{1}; Delete; }{ Volume{2}; Delete; };
f() = BooleanFragments { Volume{1}; Delete; }{ Volume{2,3}; Delete; };
If(sph)
BooleanUnion { Volume{f[1]}; Delete; }{ Volume{f[{2:#f()-2}]}; Delete; }
EndIf
// FIXME: we might want to make physical definitions work without explicit
// sync with GModel
//SyncModel;
Physical Volume(1) = {1};
Physical Volume(2) = {2};
SetFactory("OpenCASCADE");
//Mesh.Algorithm = 6;
Mesh.CharacteristicLengthMin = 0.1;
Mesh.CharacteristicLengthMax = 0.1;
DefineConstant[
sph = {0, Choices{0,1}, Name "Make sphere a single volume"}
xx = {2.2, Min -1, Max 5, Step 0.01, Name "Sphere position"}
rr = {0.5, Min 0.1, Max 3, Step 0.01, Name "Sphere radius"}
];
Block(1) = {0,0,0, 2,2,2};
Sphere(2) = {xx, 1, 1, rr};
Block(3) = {2,0,0, 4,2,2};
f() = BooleanFragments { Volume{1}; Delete; }{ Volume{2,3}; Delete; };
If(sph)
BooleanUnion { Volume{f[1]}; Delete; }{ Volume{f[{2:#f()-2}]}; Delete; }
EndIf
SetFactory("OpenCASCADE");
// from http://en.wikipedia.org/wiki/Constructive_solid_geometry
Mesh.Algorithm = 6;
Mesh.CharacteristicLengthMin = 0.4;
Mesh.CharacteristicLengthMax = 0.4;
R = DefineNumber[ 1.4 , Name "Parameters/Dimension of the Block" ];
s = DefineNumber[ .7 , Name "Parameters/Cylinder of radius s *R" ];
t = DefineNumber[ 1.25, Name "Parameters/Sphere of radius t *R" ];
R = DefineNumber[ 1.4 , Min 0.1, Max 2, Step 0.01,
Name "Parameters/Block dimension" ];
Rs = DefineNumber[ R*.7 , Min 0.1, Max 2, Step 0.01,
Name "Parameters/Cylinder radius" ];
Rt = DefineNumber[ R*1.25, Min 0.1, Max 2, Step 0.01,
Name "Parameters/Sphere radius" ];
Block(1) = {-R,-R,-R, R,R,R};
Sphere(2) = {0,0,0,R*t};
Sphere(2) = {0,0,0,Rt};
BooleanIntersection(3) = { Volume{1}; Delete; }{ Volume{2}; Delete; };
Cylinder(4) = {-2*R,0,0, 2*R,0,0, R*s};
Cylinder(5) = {0,-2*R,0, 0,2*R,0, R*s};
Cylinder(6) = {0,0,-2*R, 0,0,2*R, R*s};
Cylinder(4) = {-2*R,0,0, 2*R,0,0, Rs};
Cylinder(5) = {0,-2*R,0, 0,2*R,0, Rs};
Cylinder(6) = {0,0,-2*R, 0,0,2*R, Rs};
BooleanUnion(7) = { Volume{4}; Delete; }{ Volume{5,6}; Delete; };
BooleanDifference(8) = { Volume{3}; Delete; }{ Volume{7}; Delete; };
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment