1 // BLSURFPlugin : C++ implementation
3 // Copyright (C) 2006 OPEN CASCADE, CEA/DEN, EDF R&D
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
22 // File : BLSURFPlugin_BLSURF.cxx
23 // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA)
24 // & Aurelien ALLEAUME (DISTENE)
27 //=============================================================================
30 #include "BLSURFPlugin_BLSURF.hxx"
31 #include "BLSURFPlugin_Hypothesis.hxx"
33 #include <SMESH_Gen.hxx>
34 #include <SMESH_Mesh.hxx>
35 #include <SMESH_ControlsDef.hxx>
37 #include <SMESHDS_Mesh.hxx>
38 #include <SMDS_MeshElement.hxx>
39 #include <SMDS_MeshNode.hxx>
41 #include <utilities.h>
46 #include <BRep_Tool.hxx>
48 #include <TopExp_Explorer.hxx>
50 #include <NCollection_Map.hxx>
51 #include <Standard_ErrorHandler.hxx>
54 #include <distene/api.h>
57 #include <Geom_Surface.hxx>
58 #include <Handle_Geom_Surface.hxx>
59 #include <Geom2d_Curve.hxx>
60 #include <Handle_Geom2d_Curve.hxx>
61 #include <Geom_Curve.hxx>
62 #include <Handle_Geom_Curve.hxx>
63 #include <TopoDS_Vertex.hxx>
64 #include <TopoDS_Edge.hxx>
65 #include <TopoDS_Wire.hxx>
66 #include <TopoDS_Face.hxx>
67 #include <TopoDS_Shape.hxx>
68 #include <gp_Pnt2d.hxx>
69 #include <TopTools_IndexedMapOfShape.hxx>
70 #include <BRepTools.hxx>
72 //=============================================================================
76 //=============================================================================
78 BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId,
80 : SMESH_2D_Algo(hypId, studyId, gen)
82 MESSAGE("BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF");
85 _shapeType = (1 << TopAbs_FACE); // 1 bit /shape type
86 _compatibleHypothesis.push_back("BLSURF_Parameters");
87 _requireDescretBoundary = false;
88 _onlyUnaryInput = false;
92 //=============================================================================
96 //=============================================================================
98 BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF()
100 MESSAGE("BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF");
103 //=============================================================================
107 //=============================================================================
109 bool BLSURFPlugin_BLSURF::CheckHypothesis
111 const TopoDS_Shape& aShape,
112 SMESH_Hypothesis::Hypothesis_Status& aStatus)
116 list<const SMESHDS_Hypothesis*>::const_iterator itl;
117 const SMESHDS_Hypothesis* theHyp;
119 const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
120 int nbHyp = hyps.size();
123 aStatus = SMESH_Hypothesis::HYP_OK;
124 return true; // can work with no hypothesis
128 theHyp = (*itl); // use only the first hypothesis
130 string hypName = theHyp->GetName();
132 if (hypName == "BLSURF_Parameters")
134 _hypothesis = static_cast<const BLSURFPlugin_Hypothesis*> (theHyp);
136 if ( _hypothesis->GetPhysicalMesh() == BLSURFPlugin_Hypothesis::DefaultSize &&
137 _hypothesis->GetGeometricMesh() == BLSURFPlugin_Hypothesis::DefaultGeom )
138 // hphy_flag = 0 and hgeo_flag = 0 is not allowed (spec)
139 aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
141 aStatus = SMESH_Hypothesis::HYP_OK;
144 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
146 return aStatus == SMESH_Hypothesis::HYP_OK;
149 //=============================================================================
151 * Pass parameters to BLSURF
153 //=============================================================================
155 inline std::string to_string(double d)
157 std::ostringstream o;
162 inline std::string to_string(int i)
164 std::ostringstream o;
169 void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsurf_session_t *bls)
171 int _topology = BLSURFPlugin_Hypothesis::GetDefaultTopology();
172 int _physicalMesh = BLSURFPlugin_Hypothesis::GetDefaultPhysicalMesh();
173 double _phySize = BLSURFPlugin_Hypothesis::GetDefaultPhySize();
174 int _geometricMesh = BLSURFPlugin_Hypothesis::GetDefaultGeometricMesh();
175 double _angleMeshS = BLSURFPlugin_Hypothesis::GetDefaultAngleMeshS();
176 double _angleMeshC = BLSURFPlugin_Hypothesis::GetDefaultAngleMeshC();
177 double _gradation = BLSURFPlugin_Hypothesis::GetDefaultGradation();
178 bool _quadAllowed = BLSURFPlugin_Hypothesis::GetDefaultQuadAllowed();
179 bool _decimesh = BLSURFPlugin_Hypothesis::GetDefaultDecimesh();
180 int _verb = BLSURFPlugin_Hypothesis::GetDefaultVerbosity();
183 MESSAGE("BLSURFPlugin_BLSURF::SetParameters");
184 _topology = (int) hyp->GetTopology();
185 _physicalMesh = (int) hyp->GetPhysicalMesh();
186 _phySize = hyp->GetPhySize();
187 _geometricMesh = (int) hyp->GetGeometricMesh();
188 _angleMeshS = hyp->GetAngleMeshS();
189 _angleMeshC = hyp->GetAngleMeshC();
190 _gradation = hyp->GetGradation();
191 _quadAllowed = hyp->GetQuadAllowed();
192 _decimesh = hyp->GetDecimesh();
193 _verb = hyp->GetVerbosity();
195 if ( hyp->GetPhyMin() != ::BLSURFPlugin_Hypothesis::undefinedDouble() )
196 blsurf_set_param(bls, "hphymin", to_string(hyp->GetPhyMin()).c_str());
197 if ( hyp->GetPhyMax() != ::BLSURFPlugin_Hypothesis::undefinedDouble() )
198 blsurf_set_param(bls, "hphymax", to_string(hyp->GetPhyMax()).c_str());
199 if ( hyp->GetGeoMin() != ::BLSURFPlugin_Hypothesis::undefinedDouble() )
200 blsurf_set_param(bls, "hgeomin", to_string(hyp->GetGeoMin()).c_str());
201 if ( hyp->GetGeoMax() != ::BLSURFPlugin_Hypothesis::undefinedDouble() )
202 blsurf_set_param(bls, "hgeomax", to_string(hyp->GetGeoMax()).c_str());
204 const BLSURFPlugin_Hypothesis::TOptionValues & opts = hyp->GetOptionValues();
205 BLSURFPlugin_Hypothesis::TOptionValues::const_iterator opIt;
206 for ( opIt = opts.begin(); opIt != opts.end(); ++opIt )
207 if ( !opIt->second.empty() )
208 blsurf_set_param(bls, opIt->first.c_str(), opIt->second.c_str());
211 MESSAGE("BLSURFPlugin_BLSURF::SetParameters using defaults");
214 blsurf_set_param(bls, "topo_points", _topology > 0 ? "1" : "0");
215 blsurf_set_param(bls, "topo_curves", _topology > 0 ? "1" : "0");
216 blsurf_set_param(bls, "topo_project", _topology > 0 ? "1" : "0");
217 blsurf_set_param(bls, "clean_boundary", _topology > 1 ? "1" : "0");
218 blsurf_set_param(bls, "close_boundary", _topology > 1 ? "1" : "0");
219 blsurf_set_param(bls, "hphy_flag", to_string(_physicalMesh).c_str());
220 blsurf_set_param(bls, "hphydef", to_string(_phySize).c_str());
221 blsurf_set_param(bls, "hgeo_flag", to_string(_geometricMesh).c_str());
222 blsurf_set_param(bls, "angle_meshs", to_string(_angleMeshS).c_str());
223 blsurf_set_param(bls, "angle_meshc", to_string(_angleMeshC).c_str());
224 blsurf_set_param(bls, "gradation", to_string(_gradation).c_str());
225 blsurf_set_param(bls, "patch_independent", _decimesh ? "1" : "0");
226 blsurf_set_param(bls, "element", _quadAllowed ? "q1.0" : "p1");
227 blsurf_set_param(bls, "verb", to_string(_verb).c_str());
230 status_t curv_fun(real t, real *uv, real *dt, real *dtt, void *user_data);
231 status_t surf_fun(real *uv, real *xyz, real*du, real *dv,
232 real *duu, real *duv, real *dvv, void *user_data);
233 status_t message_callback(message_t *msg, void *user_data);
235 //=============================================================================
239 //=============================================================================
241 bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) {
243 MESSAGE("BLSURFPlugin_BLSURF::Compute");
245 if (aShape.ShapeType() == TopAbs_COMPOUND) {
246 cout << " the shape is a COMPOUND" << endl;
249 cout << " the shape is UNKNOWN" << endl;
252 context_t *ctx = context_new();
253 context_set_message_callback(ctx, message_callback, &_comment);
255 cad_t *c = cad_new(ctx);
257 TopTools_IndexedMapOfShape fmap;
258 TopTools_IndexedMapOfShape emap;
259 TopTools_IndexedMapOfShape pmap;
260 vector<Handle(Geom2d_Curve)> curves;
261 vector<Handle(Geom_Surface)> surfaces;
270 for (TopExp_Explorer face_iter(aShape,TopAbs_FACE);face_iter.More();face_iter.Next()) {
271 TopoDS_Face f=TopoDS::Face(face_iter.Current());
272 if (fmap.FindIndex(f) > 0)
277 surfaces.push_back(BRep_Tool::Surface(f));
278 cad_face_t *fce = cad_face_new(c, iface, surf_fun, surfaces.back());
279 cad_face_set_tag(fce, iface);
280 if(f.Orientation() != TopAbs_FORWARD){
281 cad_face_set_orientation(fce, CAD_ORIENTATION_REVERSED);
283 cad_face_set_orientation(fce, CAD_ORIENTATION_FORWARD);
286 for (TopExp_Explorer edge_iter(f,TopAbs_EDGE);edge_iter.More();edge_iter.Next()) {
287 TopoDS_Edge e = TopoDS::Edge(edge_iter.Current());
288 int ic = emap.FindIndex(e);
293 curves.push_back(BRep_Tool::CurveOnSurface(e, f, tmin, tmax));
294 cad_edge_t *edg = cad_edge_new(fce, ic, tmin, tmax, curv_fun, curves.back());
295 cad_edge_set_tag(edg, ic);
296 cad_edge_set_property(edg, EDGE_PROPERTY_SOFT_REQUIRED);
300 gp_Pnt2d e0 = curves.back()->Value(tmin);
301 gp_Pnt ee0 = surfaces.back()->Value(e0.X(), e0.Y());
302 Standard_Real d1=0,d2=0;
303 for (TopExp_Explorer ex_edge(e ,TopAbs_VERTEX); ex_edge.More(); ex_edge.Next()) {
304 TopoDS_Vertex v = TopoDS::Vertex(ex_edge.Current());
309 d1 = ee0.SquareDistance(BRep_Tool::Pnt(v));
312 d2 = ee0.SquareDistance(BRep_Tool::Pnt(v));
314 *ip = pmap.FindIndex(v);
320 cout << "An edge does not have 2 extremities." << endl;
323 cad_edge_set_extremities(edg, ip1, ip2);
325 cad_edge_set_extremities(edg, ip2, ip1);
333 blsurf_session_t *bls = blsurf_session_new(ctx);
334 blsurf_data_set_cad(bls, c);
336 SetParameters(_hypothesis, bls);
339 cout << "Beginning of Surface Mesh generation" << endl;
342 status_t status = STATUS_ERROR;
346 status = blsurf_compute_mesh(bls);
348 catch ( std::exception& exc ) {
349 // if ( !_comment.empty() )
351 _comment += exc.what();
353 catch (Standard_Failure& ex) {
354 // if ( !_comment.empty() )
356 _comment += ex.DynamicType()->Name();
357 if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) {
359 _comment += ex.GetMessageString();
363 if ( _comment.empty() )
364 _comment = "Exception in blsurf_compute_mesh()";
366 if ( status != STATUS_OK) {
367 blsurf_session_delete(bls);
371 return error(_comment);
376 cout << "End of Surface Mesh generation" << endl;
380 blsurf_data_get_mesh(bls, &msh);
382 blsurf_session_delete(bls);
386 return error(_comment);
390 integer nv, ne, nt, nq, vtx[4], tag;
393 mesh_get_vertex_count(msh, &nv);
394 mesh_get_edge_count(msh, &ne);
395 mesh_get_triangle_count(msh, &nt);
396 mesh_get_quadrangle_count(msh, &nq);
399 SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
400 SMDS_MeshNode** nodes = new SMDS_MeshNode*[nv+1];
401 bool* tags = new bool[nv+1];
403 for(int iv=1;iv<=nv;iv++) {
404 mesh_get_vertex_coordinates(msh, iv, xyz);
405 mesh_get_vertex_tag(msh, iv, &tag);
406 nodes[iv] = meshDS->AddNode(xyz[0], xyz[1], xyz[2]);
407 // internal point are tagged to zero
409 meshDS->SetNodeOnVertex(nodes[iv], TopoDS::Vertex(pmap(tag)));
416 for(int it=1;it<=ne;it++) {
417 mesh_get_edge_vertices(msh, it, vtx);
418 SMDS_MeshEdge* edg = meshDS->AddEdge(nodes[vtx[0]], nodes[vtx[1]]);
419 mesh_get_edge_tag(msh, it, &tag);
422 meshDS->SetNodeOnEdge(nodes[vtx[0]], TopoDS::Edge(emap(tag)));
423 tags[vtx[0]] = false;
426 meshDS->SetNodeOnEdge(nodes[vtx[1]], TopoDS::Edge(emap(tag)));
427 tags[vtx[1]] = false;
429 meshDS->SetMeshElementOnShape(edg, TopoDS::Edge(emap(tag)));
433 for(int it=1;it<=nt;it++) {
434 mesh_get_triangle_vertices(msh, it, vtx);
435 SMDS_MeshFace* tri = meshDS->AddFace(nodes[vtx[0]], nodes[vtx[1]], nodes[vtx[2]]);
436 mesh_get_triangle_tag(msh, it, &tag);
437 meshDS->SetMeshElementOnShape(tri, TopoDS::Face(fmap(tag)));
439 meshDS->SetNodeOnFace(nodes[vtx[0]], TopoDS::Face(fmap(tag)));
440 tags[vtx[0]] = false;
443 meshDS->SetNodeOnFace(nodes[vtx[1]], TopoDS::Face(fmap(tag)));
444 tags[vtx[1]] = false;
447 meshDS->SetNodeOnFace(nodes[vtx[2]], TopoDS::Face(fmap(tag)));
448 tags[vtx[2]] = false;
452 for(int it=1;it<=nq;it++) {
453 mesh_get_quadrangle_vertices(msh, it, vtx);
454 SMDS_MeshFace* quad = meshDS->AddFace(nodes[vtx[0]], nodes[vtx[1]], nodes[vtx[2]], nodes[vtx[3]]);
455 mesh_get_quadrangle_tag(msh, it, &tag);
456 meshDS->SetMeshElementOnShape(quad, TopoDS::Face(fmap(tag)));
458 meshDS->SetNodeOnFace(nodes[vtx[0]], TopoDS::Face(fmap(tag)));
459 tags[vtx[0]] = false;
462 meshDS->SetNodeOnFace(nodes[vtx[1]], TopoDS::Face(fmap(tag)));
463 tags[vtx[1]] = false;
466 meshDS->SetNodeOnFace(nodes[vtx[2]], TopoDS::Face(fmap(tag)));
467 tags[vtx[2]] = false;
470 meshDS->SetNodeOnFace(nodes[vtx[3]], TopoDS::Face(fmap(tag)));
471 tags[vtx[3]] = false;
477 /* release the mesh object */
478 blsurf_data_regain_mesh(bls, msh);
480 /* clean up everything */
481 blsurf_session_delete(bls);
489 //=============================================================================
493 //=============================================================================
495 ostream & BLSURFPlugin_BLSURF::SaveTo(ostream & save)
500 //=============================================================================
504 //=============================================================================
506 istream & BLSURFPlugin_BLSURF::LoadFrom(istream & load)
511 //=============================================================================
515 //=============================================================================
517 ostream & operator << (ostream & save, BLSURFPlugin_BLSURF & hyp)
519 return hyp.SaveTo( save );
522 //=============================================================================
526 //=============================================================================
528 istream & operator >> (istream & load, BLSURFPlugin_BLSURF & hyp)
530 return hyp.LoadFrom( load );
533 status_t curv_fun(real t, real *uv, real *dt, real *dtt, void *user_data)
535 const Geom2d_Curve*pargeo = (const Geom2d_Curve*) user_data;
540 uv[0]=P.X(); uv[1]=P.Y();
546 dt[0]=V1.X(); dt[1]=V1.Y();
552 dtt[0]=V2.X(); dtt[1]=V2.Y();
558 status_t surf_fun(real *uv, real *xyz, real*du, real *dv,
559 real *duu, real *duv, real *dvv, void *user_data)
561 const Geom_Surface* geometry = (const Geom_Surface*) user_data;
565 P=geometry->Value(uv[0],uv[1]); // S.D0(U,V,P);
566 xyz[0]=P.X(); xyz[1]=P.Y(); xyz[2]=P.Z();
573 geometry->D1(uv[0],uv[1],P,D1U,D1V);
574 du[0]=D1U.X(); du[1]=D1U.Y(); du[2]=D1U.Z();
575 dv[0]=D1V.X(); dv[1]=D1V.Y(); dv[2]=D1V.Z();
578 if(duu && duv && dvv){
583 geometry->D2(uv[0],uv[1],P,D1U,D1V,D2U,D2V,D2UV);
584 duu[0]=D2U.X(); duu[1]=D2U.Y(); duu[2]=D2U.Z();
585 duv[0]=D2UV.X(); duv[1]=D2UV.Y(); duv[2]=D2UV.Z();
586 dvv[0]=D2V.X(); dvv[1]=D2V.Y(); dvv[2]=D2V.Z();
592 status_t message_callback(message_t *msg, void *user_data)
594 integer errnumber = 0;
596 message_get_number(msg, &errnumber);
597 message_get_description(msg, &desc);
598 if ( errnumber < 0 ) {
599 string * error = (string*)user_data;
600 // if ( !error->empty() )
602 // remove ^A from the tail
603 int len = strlen( desc );
604 while (len > 0 && desc[len-1] != '\n')
606 error->append( desc, len );