1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File : BLSURFPlugin_BLSURF.cxx
21 // Authors : Francis KLOSS (OCC) & Patrick LAUG (INRIA) & Lioka RAZAFINDRAZAKA (CEA)
22 // & Aurelien ALLEAUME (DISTENE)
25 #include "BLSURFPlugin_BLSURF.hxx"
26 #include "BLSURFPlugin_Hypothesis.hxx"
28 #include <structmember.h>
31 #include <SMESH_Gen.hxx>
32 #include <SMESH_Mesh.hxx>
33 #include <SMESH_ControlsDef.hxx>
34 #include <SMESHGUI_Utils.h>
36 #include <SMESHDS_Mesh.hxx>
37 #include <SMDS_MeshElement.hxx>
38 #include <SMDS_MeshNode.hxx>
40 #include <utilities.h>
45 #include <tr1/unordered_map>
48 #include <BRep_Tool.hxx>
50 #include <TopExp_Explorer.hxx>
52 #include <NCollection_Map.hxx>
53 #include <Standard_ErrorHandler.hxx>
56 #include <distene/api.h>
59 #include <Geom_Surface.hxx>
60 #include <Handle_Geom_Surface.hxx>
61 #include <Geom2d_Curve.hxx>
62 #include <Handle_Geom2d_Curve.hxx>
63 #include <Geom_Curve.hxx>
64 #include <Handle_Geom_Curve.hxx>
65 #include <TopoDS_Vertex.hxx>
66 #include <TopoDS_Edge.hxx>
67 #include <TopoDS_Wire.hxx>
68 #include <TopoDS_Face.hxx>
69 #include <TopoDS_Shape.hxx>
70 #include <gp_Pnt2d.hxx>
71 #include <TopTools_IndexedMapOfShape.hxx>
72 #include <BRepTools.hxx>
78 #include <GeomSelectionTools.h>
81 /* ==================================
82 * =========== PYTHON ==============
83 * ==================================*/
92 PyStdOut_dealloc(PyStdOut *self)
98 PyStdOut_write(PyStdOut *self, PyObject *args)
102 if (!PyArg_ParseTuple(args, "t#:write",&c, &l))
106 *(self->out)=*(self->out)+c;
112 static PyMethodDef PyStdOut_methods[] = {
113 {"write", (PyCFunction)PyStdOut_write, METH_VARARGS,
114 PyDoc_STR("write(string) -> None")},
115 {NULL, NULL} /* sentinel */
118 static PyMemberDef PyStdOut_memberlist[] = {
119 {"softspace", T_INT, offsetof(PyStdOut, softspace), 0,
120 "flag indicating that a space needs to be printed; used by print"},
121 {NULL} /* Sentinel */
124 static PyTypeObject PyStdOut_Type = {
125 /* The ob_type field must be initialized in the module init function
126 * to be portable to Windows without using C++. */
127 PyObject_HEAD_INIT(NULL)
130 sizeof(PyStdOut), /*tp_basicsize*/
133 (destructor)PyStdOut_dealloc, /*tp_dealloc*/
140 0, /*tp_as_sequence*/
145 PyObject_GenericGetAttr, /*tp_getattro*/
146 /* softspace is writable: we must supply tp_setattro */
147 PyObject_GenericSetAttr, /* tp_setattro */
149 Py_TPFLAGS_DEFAULT, /*tp_flags*/
153 0, /*tp_richcompare*/
154 0, /*tp_weaklistoffset*/
157 PyStdOut_methods, /*tp_methods*/
158 PyStdOut_memberlist, /*tp_members*/
172 PyObject * newPyStdOut( std::string& out )
175 self = PyObject_New(PyStdOut, &PyStdOut_Type);
180 return (PyObject*)self;
184 ////////////////////////END PYTHON///////////////////////////
187 //////////////////TO WELL DEFINE UNORDERED TOPODS_MAP////////
192 struct hash<TopoDS_Face>
193 : public std::unary_function<TopoDS_Face,std::size_t>
195 std::size_t operator() (const TopoDS_Face & Face) const
196 { return Face.HashCode(471662);}
197 // { return Face.HashCode(std::numeric_limits<int>::max());}
201 struct hash<TopoDS_Edge>
202 : public std::unary_function<TopoDS_Edge,std::size_t>
204 std::size_t operator() (const TopoDS_Edge & Edge) const
205 { return Edge.HashCode(471662);}
206 // { return Face.HashCode(std::numeric_limits<int>::max());}
210 struct hash<TopoDS_Vertex>
211 : public std::unary_function<TopoDS_Vertex,std::size_t>
213 std::size_t operator() (const TopoDS_Vertex & Vertex) const
214 { return Vertex.HashCode(471662);}
215 // { return Face.HashCode(std::numeric_limits<int>::max());}
220 //////////////////MY MAPS////////////////////////////////////////
221 std::tr1::unordered_map<TopoDS_Face,string> Face2SizeMap;
222 std::tr1::unordered_map<TopoDS_Edge,string> Edge2SizeMap;
223 std::tr1::unordered_map<TopoDS_Vertex,string> Vertex2SizeMap;
224 std::map<int,PyObject*> FaceId2PythonSmp;
225 std::map<int,PyObject*> EdgeId2PythonSmp;
226 std::map<int,PyObject*> VertexId2PythonSmp;
229 bool HasSizeMapOnFace=false;
230 bool HasSizeMapOnEdge=false;
231 bool HasSizeMapOnVertex=false;
233 //=============================================================================
237 //=============================================================================
239 BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF(int hypId, int studyId,
241 : SMESH_2D_Algo(hypId, studyId, gen)
243 MESSAGE("BLSURFPlugin_BLSURF::BLSURFPlugin_BLSURF");
246 _shapeType = (1 << TopAbs_FACE); // 1 bit /shape type
247 _compatibleHypothesis.push_back("BLSURF_Parameters");
248 _requireDescretBoundary = false;
249 _onlyUnaryInput = false;
253 /* Initialize the Python interpreter */
254 assert(Py_IsInitialized());
255 PyGILState_STATE gstate;
256 gstate = PyGILState_Ensure();
259 main_mod = PyImport_AddModule("__main__");
262 main_dict = PyModule_GetDict(main_mod);
264 PyRun_SimpleString("from math import *");
265 PyGILState_Release(gstate);
269 //=============================================================================
273 //=============================================================================
275 BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF()
277 MESSAGE("BLSURFPlugin_BLSURF::~BLSURFPlugin_BLSURF");
281 //=============================================================================
285 //=============================================================================
287 bool BLSURFPlugin_BLSURF::CheckHypothesis
289 const TopoDS_Shape& aShape,
290 SMESH_Hypothesis::Hypothesis_Status& aStatus)
294 list<const SMESHDS_Hypothesis*>::const_iterator itl;
295 const SMESHDS_Hypothesis* theHyp;
297 const list<const SMESHDS_Hypothesis*>& hyps = GetUsedHypothesis(aMesh, aShape);
298 int nbHyp = hyps.size();
301 aStatus = SMESH_Hypothesis::HYP_OK;
302 return true; // can work with no hypothesis
306 theHyp = (*itl); // use only the first hypothesis
308 string hypName = theHyp->GetName();
310 if (hypName == "BLSURF_Parameters")
312 _hypothesis = static_cast<const BLSURFPlugin_Hypothesis*> (theHyp);
314 if ( _hypothesis->GetPhysicalMesh() == BLSURFPlugin_Hypothesis::DefaultSize &&
315 _hypothesis->GetGeometricMesh() == BLSURFPlugin_Hypothesis::DefaultGeom )
316 // hphy_flag = 0 and hgeo_flag = 0 is not allowed (spec)
317 aStatus = SMESH_Hypothesis::HYP_BAD_PARAMETER;
319 aStatus = SMESH_Hypothesis::HYP_OK;
322 aStatus = SMESH_Hypothesis::HYP_INCOMPATIBLE;
324 return aStatus == SMESH_Hypothesis::HYP_OK;
327 //=============================================================================
329 * Pass parameters to BLSURF
331 //=============================================================================
333 inline std::string to_string(double d)
335 std::ostringstream o;
340 inline std::string to_string(int i)
342 std::ostringstream o;
347 double _smp_phy_size;
348 status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data);
349 status_t size_on_edge(integer edge_id, real t, real *size, void *user_data);
350 status_t size_on_vertex(integer vertex_id, real *size, void *user_data);
352 double my_u_min=1e6,my_v_min=1e6,my_u_max=-1e6,my_v_max=-1e6;
354 void BLSURFPlugin_BLSURF::SetParameters(const BLSURFPlugin_Hypothesis* hyp, blsurf_session_t *bls)
356 int _topology = BLSURFPlugin_Hypothesis::GetDefaultTopology();
357 int _physicalMesh = BLSURFPlugin_Hypothesis::GetDefaultPhysicalMesh();
358 double _phySize = BLSURFPlugin_Hypothesis::GetDefaultPhySize();
359 int _geometricMesh = BLSURFPlugin_Hypothesis::GetDefaultGeometricMesh();
360 double _angleMeshS = BLSURFPlugin_Hypothesis::GetDefaultAngleMeshS();
361 double _angleMeshC = BLSURFPlugin_Hypothesis::GetDefaultAngleMeshC();
362 double _gradation = BLSURFPlugin_Hypothesis::GetDefaultGradation();
363 bool _quadAllowed = BLSURFPlugin_Hypothesis::GetDefaultQuadAllowed();
364 bool _decimesh = BLSURFPlugin_Hypothesis::GetDefaultDecimesh();
365 int _verb = BLSURFPlugin_Hypothesis::GetDefaultVerbosity();
368 MESSAGE("BLSURFPlugin_BLSURF::SetParameters");
369 _topology = (int) hyp->GetTopology();
370 _physicalMesh = (int) hyp->GetPhysicalMesh();
371 _phySize = hyp->GetPhySize();
372 _geometricMesh = (int) hyp->GetGeometricMesh();
373 _angleMeshS = hyp->GetAngleMeshS();
374 _angleMeshC = hyp->GetAngleMeshC();
375 _gradation = hyp->GetGradation();
376 _quadAllowed = hyp->GetQuadAllowed();
377 _decimesh = hyp->GetDecimesh();
378 _verb = hyp->GetVerbosity();
380 if ( hyp->GetPhyMin() != ::BLSURFPlugin_Hypothesis::undefinedDouble() )
381 blsurf_set_param(bls, "hphymin", to_string(hyp->GetPhyMin()).c_str());
382 if ( hyp->GetPhyMax() != ::BLSURFPlugin_Hypothesis::undefinedDouble() )
383 blsurf_set_param(bls, "hphymax", to_string(hyp->GetPhyMax()).c_str());
384 if ( hyp->GetGeoMin() != ::BLSURFPlugin_Hypothesis::undefinedDouble() )
385 blsurf_set_param(bls, "hgeomin", to_string(hyp->GetGeoMin()).c_str());
386 if ( hyp->GetGeoMax() != ::BLSURFPlugin_Hypothesis::undefinedDouble() )
387 blsurf_set_param(bls, "hgeomax", to_string(hyp->GetGeoMax()).c_str());
389 const BLSURFPlugin_Hypothesis::TOptionValues & opts = hyp->GetOptionValues();
390 BLSURFPlugin_Hypothesis::TOptionValues::const_iterator opIt;
391 for ( opIt = opts.begin(); opIt != opts.end(); ++opIt )
392 if ( !opIt->second.empty() ) {
394 cout << "blsurf_set_param(): " << opIt->first << " = " << opIt->second << endl;
396 blsurf_set_param(bls, opIt->first.c_str(), opIt->second.c_str());
400 MESSAGE("BLSURFPlugin_BLSURF::SetParameters using defaults");
402 _smp_phy_size = _phySize;
403 blsurf_set_param(bls, "topo_points", _topology > 0 ? "1" : "0");
404 blsurf_set_param(bls, "topo_curves", _topology > 0 ? "1" : "0");
405 blsurf_set_param(bls, "topo_project", _topology > 0 ? "1" : "0");
406 blsurf_set_param(bls, "clean_boundary", _topology > 1 ? "1" : "0");
407 blsurf_set_param(bls, "close_boundary", _topology > 1 ? "1" : "0");
408 blsurf_set_param(bls, "hphy_flag", to_string(_physicalMesh).c_str());
409 // blsurf_set_param(bls, "hphy_flag", "2");
410 if ((to_string(_physicalMesh))=="2"){
411 MESSAGE("Setting a Size Map");
412 const BLSURFPlugin_Hypothesis::TSizeMap & sizeMaps = hyp->GetSizeMapEntries();
413 BLSURFPlugin_Hypothesis::TSizeMap::const_iterator smIt;
414 GeomSelectionTools* GeomST;
415 GeomST=new GeomSelectionTools::GeomSelectionTools( SMESH::GetActiveStudyDocument());
417 Face2SizeMap.clear();
418 Edge2SizeMap.clear();
419 Vertex2SizeMap.clear();
421 for ( smIt = sizeMaps.begin(); smIt != sizeMaps.end(); ++smIt ) {
422 if ( !smIt->second.empty() ) {
424 cout << "blsurf_set_sizeMap(): " << smIt->first << " = " << smIt->second << endl;
426 TopoDS_Shape GeomShape=GeomST->entryToShape(smIt->first);
427 TopAbs_ShapeEnum GeomType= GeomShape.ShapeType();
428 if (GeomType==TopAbs_FACE){
429 HasSizeMapOnFace=true;
430 Face2SizeMap[TopoDS::Face(GeomShape)]= smIt->second;
432 if (GeomType==TopAbs_EDGE){
433 HasSizeMapOnEdge=true;
434 HasSizeMapOnFace=true;
435 Edge2SizeMap[TopoDS::Edge(GeomShape)]= smIt->second;
437 if (GeomType==TopAbs_VERTEX){
438 HasSizeMapOnVertex=true;
439 HasSizeMapOnEdge=true;
440 HasSizeMapOnFace=true;
441 Vertex2SizeMap[TopoDS::Vertex(GeomShape)]= smIt->second;
445 // if (HasSizeMapOnFace){
446 // In all size map cases (hphy_flag = 2), at least map on face must be defined
447 std::cout << "Setting Size Map on FACES " << std::endl;
448 blsurf_data_set_sizemap_iso_cad_face(bls, size_on_surface, &_smp_phy_size);
451 if (HasSizeMapOnEdge){
452 std::cout << "Setting Size Map on EDGES " << std::endl;
453 blsurf_data_set_sizemap_iso_cad_edge(bls, size_on_edge, &_smp_phy_size);
455 if (HasSizeMapOnVertex){
456 std::cout << "Setting Size Map on VERTICES " << std::endl;
457 blsurf_data_set_sizemap_iso_cad_point(bls, size_on_vertex, &_smp_phy_size);
460 blsurf_set_param(bls, "hphydef", to_string(_phySize).c_str());
461 blsurf_set_param(bls, "hgeo_flag", to_string(_geometricMesh).c_str());
462 blsurf_set_param(bls, "angle_meshs", to_string(_angleMeshS).c_str());
463 blsurf_set_param(bls, "angle_meshc", to_string(_angleMeshC).c_str());
464 blsurf_set_param(bls, "gradation", to_string(_gradation).c_str());
465 blsurf_set_param(bls, "patch_independent", _decimesh ? "1" : "0");
466 blsurf_set_param(bls, "element", _quadAllowed ? "q1.0" : "p1");
467 blsurf_set_param(bls, "verb", to_string(_verb).c_str());
470 status_t curv_fun(real t, real *uv, real *dt, real *dtt, void *user_data);
471 status_t surf_fun(real *uv, real *xyz, real*du, real *dv,
472 real *duu, real *duv, real *dvv, void *user_data);
473 status_t message_callback(message_t *msg, void *user_data);
475 //=============================================================================
479 //=============================================================================
481 bool BLSURFPlugin_BLSURF::Compute(SMESH_Mesh& aMesh, const TopoDS_Shape& aShape) {
483 MESSAGE("BLSURFPlugin_BLSURF::Compute");
485 if (aShape.ShapeType() == TopAbs_COMPOUND) {
486 cout << " the shape is a COMPOUND" << endl;
489 cout << " the shape is UNKNOWN" << endl;
492 context_t *ctx = context_new();
493 context_set_message_callback(ctx, message_callback, &_comment);
495 cad_t *c = cad_new(ctx);
497 blsurf_session_t *bls = blsurf_session_new(ctx);
500 SetParameters(_hypothesis, bls);
502 TopTools_IndexedMapOfShape fmap;
503 TopTools_IndexedMapOfShape emap;
504 TopTools_IndexedMapOfShape pmap;
505 vector<Handle(Geom2d_Curve)> curves;
506 vector<Handle(Geom_Surface)> surfaces;
511 FaceId2PythonSmp.clear();
513 EdgeId2PythonSmp.clear();
515 VertexId2PythonSmp.clear();
519 assert(Py_IsInitialized());
520 PyGILState_STATE gstate;
521 gstate = PyGILState_Ensure();
529 for (TopExp_Explorer face_iter(aShape,TopAbs_FACE);face_iter.More();face_iter.Next()) {
530 TopoDS_Face f=TopoDS::Face(face_iter.Current());
531 if (fmap.FindIndex(f) > 0)
536 surfaces.push_back(BRep_Tool::Surface(f));
537 // Get bound values of uv surface
538 //BRep_Tool::Surface(f)->Bounds(u_min,u_max,v_min,v_max);
539 //std::cout << "BRep_Tool::Surface(f)->Bounds(u_min,u_max,v_min,v_max): " << u_min << ", " << u_max << ", " << v_min << ", " << v_max << std::endl;
540 if ((HasSizeMapOnFace) && Face2SizeMap.find(f)!=Face2SizeMap.end()){
541 // Expr To Python function, verification is performed at validation in GUI
542 PyObject * obj = NULL;
543 obj= PyRun_String(Face2SizeMap[f].c_str(), Py_file_input, main_dict, NULL);
545 PyObject * func = NULL;
546 func = PyObject_GetAttrString(main_mod, "f");
547 FaceId2PythonSmp[iface]=func;
548 Face2SizeMap.erase(f);
550 cad_face_t *fce = cad_face_new(c, iface, surf_fun, surfaces.back());
551 cad_face_set_tag(fce, iface);
552 if(f.Orientation() != TopAbs_FORWARD){
553 cad_face_set_orientation(fce, CAD_ORIENTATION_REVERSED);
555 cad_face_set_orientation(fce, CAD_ORIENTATION_FORWARD);
558 for (TopExp_Explorer edge_iter(f,TopAbs_EDGE);edge_iter.More();edge_iter.Next()) {
559 TopoDS_Edge e = TopoDS::Edge(edge_iter.Current());
560 int ic = emap.FindIndex(e);
565 curves.push_back(BRep_Tool::CurveOnSurface(e, f, tmin, tmax));
566 if ((HasSizeMapOnEdge) && Edge2SizeMap.find(e)!=Edge2SizeMap.end()){
567 // Expr To Python function, verification is performed at validation in GUI
568 PyObject * obj = NULL;
569 obj= PyRun_String(Edge2SizeMap[e].c_str(), Py_file_input, main_dict, NULL);
571 PyObject * func = NULL;
572 func = PyObject_GetAttrString(main_mod, "f");
573 EdgeId2PythonSmp[ic]=func;
574 Edge2SizeMap.erase(e);
576 cad_edge_t *edg = cad_edge_new(fce, ic, tmin, tmax, curv_fun, curves.back());
577 cad_edge_set_tag(edg, ic);
578 cad_edge_set_property(edg, EDGE_PROPERTY_SOFT_REQUIRED);
579 if (e.Orientation() == TopAbs_INTERNAL)
580 cad_edge_set_property(edg, EDGE_PROPERTY_INTERNAL);
584 gp_Pnt2d e0 = curves.back()->Value(tmin);
585 gp_Pnt ee0 = surfaces.back()->Value(e0.X(), e0.Y());
586 Standard_Real d1=0,d2=0;
587 for (TopExp_Explorer ex_edge(e ,TopAbs_VERTEX); ex_edge.More(); ex_edge.Next()) {
588 TopoDS_Vertex v = TopoDS::Vertex(ex_edge.Current());
592 d1 = ee0.SquareDistance(BRep_Tool::Pnt(v));
595 d2 = ee0.SquareDistance(BRep_Tool::Pnt(v));
597 *ip = pmap.FindIndex(v);
600 if ((HasSizeMapOnVertex) && Vertex2SizeMap.find(v)!=Vertex2SizeMap.end()){
601 // Expr To Python function, verification is performed at validation in GUI
602 PyObject * obj = NULL;
603 obj= PyRun_String(Vertex2SizeMap[v].c_str(), Py_file_input, main_dict, NULL);
605 PyObject * func = NULL;
606 func = PyObject_GetAttrString(main_mod, "f");
607 VertexId2PythonSmp[*ip]=func;
608 Vertex2SizeMap.erase(v);
613 cout << "An edge does not have 2 extremities." << endl;
616 cad_edge_set_extremities(edg, ip1, ip2);
618 cad_edge_set_extremities(edg, ip2, ip1);
624 PyGILState_Release(gstate);
626 blsurf_data_set_cad(bls, c);
629 cout << "Beginning of Surface Mesh generation" << endl;
632 // Issue 0019864. On DebianSarge, FE signals do not obey to OSD::SetSignal(false)
634 feclearexcept( FE_ALL_EXCEPT );
635 int oldFEFlags = fedisableexcept( FE_ALL_EXCEPT );
638 status_t status = STATUS_ERROR;
643 status = blsurf_compute_mesh(bls);
646 catch ( std::exception& exc ) {
647 _comment += exc.what();
649 catch (Standard_Failure& ex) {
650 _comment += ex.DynamicType()->Name();
651 if ( ex.GetMessageString() && strlen( ex.GetMessageString() )) {
653 _comment += ex.GetMessageString();
657 if ( _comment.empty() )
658 _comment = "Exception in blsurf_compute_mesh()";
660 if ( status != STATUS_OK) {
661 blsurf_session_delete(bls);
665 return error(_comment);
669 cout << "End of Surface Mesh generation" << endl;
672 cout << "****************** U MIN: " << my_u_min << endl;
673 cout << "****************** V MIN: " << my_v_min << endl;
674 cout << "****************** U MAX: " << my_u_max << endl;
675 cout << "****************** V MAX: " << my_v_max << endl;
678 blsurf_data_get_mesh(bls, &msh);
680 blsurf_session_delete(bls);
684 return error(_comment);
688 integer nv, ne, nt, nq, vtx[4], tag;
691 mesh_get_vertex_count(msh, &nv);
692 mesh_get_edge_count(msh, &ne);
693 mesh_get_triangle_count(msh, &nt);
694 mesh_get_quadrangle_count(msh, &nq);
697 SMESHDS_Mesh* meshDS = aMesh.GetMeshDS();
698 SMDS_MeshNode** nodes = new SMDS_MeshNode*[nv+1];
699 bool* tags = new bool[nv+1];
701 for(int iv=1;iv<=nv;iv++) {
702 mesh_get_vertex_coordinates(msh, iv, xyz);
703 mesh_get_vertex_tag(msh, iv, &tag);
704 nodes[iv] = meshDS->AddNode(xyz[0], xyz[1], xyz[2]);
705 // internal point are tagged to zero
707 meshDS->SetNodeOnVertex(nodes[iv], TopoDS::Vertex(pmap(tag)));
714 for(int it=1;it<=ne;it++) {
715 mesh_get_edge_vertices(msh, it, vtx);
716 SMDS_MeshEdge* edg = meshDS->AddEdge(nodes[vtx[0]], nodes[vtx[1]]);
717 mesh_get_edge_tag(msh, it, &tag);
720 meshDS->SetNodeOnEdge(nodes[vtx[0]], TopoDS::Edge(emap(tag)));
721 tags[vtx[0]] = false;
724 meshDS->SetNodeOnEdge(nodes[vtx[1]], TopoDS::Edge(emap(tag)));
725 tags[vtx[1]] = false;
727 meshDS->SetMeshElementOnShape(edg, TopoDS::Edge(emap(tag)));
731 for(int it=1;it<=nt;it++) {
732 mesh_get_triangle_vertices(msh, it, vtx);
733 SMDS_MeshFace* tri = meshDS->AddFace(nodes[vtx[0]], nodes[vtx[1]], nodes[vtx[2]]);
734 mesh_get_triangle_tag(msh, it, &tag);
735 meshDS->SetMeshElementOnShape(tri, TopoDS::Face(fmap(tag)));
737 meshDS->SetNodeOnFace(nodes[vtx[0]], TopoDS::Face(fmap(tag)));
738 tags[vtx[0]] = false;
741 meshDS->SetNodeOnFace(nodes[vtx[1]], TopoDS::Face(fmap(tag)));
742 tags[vtx[1]] = false;
745 meshDS->SetNodeOnFace(nodes[vtx[2]], TopoDS::Face(fmap(tag)));
746 tags[vtx[2]] = false;
750 for(int it=1;it<=nq;it++) {
751 mesh_get_quadrangle_vertices(msh, it, vtx);
752 SMDS_MeshFace* quad = meshDS->AddFace(nodes[vtx[0]], nodes[vtx[1]], nodes[vtx[2]], nodes[vtx[3]]);
753 mesh_get_quadrangle_tag(msh, it, &tag);
754 meshDS->SetMeshElementOnShape(quad, TopoDS::Face(fmap(tag)));
756 meshDS->SetNodeOnFace(nodes[vtx[0]], TopoDS::Face(fmap(tag)));
757 tags[vtx[0]] = false;
760 meshDS->SetNodeOnFace(nodes[vtx[1]], TopoDS::Face(fmap(tag)));
761 tags[vtx[1]] = false;
764 meshDS->SetNodeOnFace(nodes[vtx[2]], TopoDS::Face(fmap(tag)));
765 tags[vtx[2]] = false;
768 meshDS->SetNodeOnFace(nodes[vtx[3]], TopoDS::Face(fmap(tag)));
769 tags[vtx[3]] = false;
775 /* release the mesh object */
776 blsurf_data_regain_mesh(bls, msh);
778 /* clean up everything */
779 blsurf_session_delete(bls);
784 // Issue 0019864. On DebianSarge, FE signals do not obey to OSD::SetSignal(false)
786 if ( oldFEFlags > 0 )
787 feenableexcept( oldFEFlags );
788 feclearexcept( FE_ALL_EXCEPT );
794 //=============================================================================
798 //=============================================================================
800 ostream & BLSURFPlugin_BLSURF::SaveTo(ostream & save)
805 //=============================================================================
809 //=============================================================================
811 istream & BLSURFPlugin_BLSURF::LoadFrom(istream & load)
816 //=============================================================================
820 //=============================================================================
822 ostream & operator << (ostream & save, BLSURFPlugin_BLSURF & hyp)
824 return hyp.SaveTo( save );
827 //=============================================================================
831 //=============================================================================
833 istream & operator >> (istream & load, BLSURFPlugin_BLSURF & hyp)
835 return hyp.LoadFrom( load );
838 status_t curv_fun(real t, real *uv, real *dt, real *dtt, void *user_data)
840 const Geom2d_Curve*pargeo = (const Geom2d_Curve*) user_data;
845 uv[0]=P.X(); uv[1]=P.Y();
851 dt[0]=V1.X(); dt[1]=V1.Y();
857 dtt[0]=V2.X(); dtt[1]=V2.Y();
863 status_t surf_fun(real *uv, real *xyz, real*du, real *dv,
864 real *duu, real *duv, real *dvv, void *user_data)
866 const Geom_Surface* geometry = (const Geom_Surface*) user_data;
870 P=geometry->Value(uv[0],uv[1]); // S.D0(U,V,P);
871 xyz[0]=P.X(); xyz[1]=P.Y(); xyz[2]=P.Z();
878 geometry->D1(uv[0],uv[1],P,D1U,D1V);
879 du[0]=D1U.X(); du[1]=D1U.Y(); du[2]=D1U.Z();
880 dv[0]=D1V.X(); dv[1]=D1V.Y(); dv[2]=D1V.Z();
883 if(duu && duv && dvv){
888 geometry->D2(uv[0],uv[1],P,D1U,D1V,D2U,D2V,D2UV);
889 duu[0]=D2U.X(); duu[1]=D2U.Y(); duu[2]=D2U.Z();
890 duv[0]=D2UV.X(); duv[1]=D2UV.Y(); duv[2]=D2UV.Z();
891 dvv[0]=D2V.X(); dvv[1]=D2V.Y(); dvv[2]=D2V.Z();
898 status_t size_on_surface(integer face_id, real *uv, real *size, void *user_data)
901 if (my_u_min > uv[0]) {
903 // cout << "****************** FACE ID / U MIN: " << face_id << " / " << my_u_min << endl;
905 if (my_v_min > uv[1]) {
907 // cout << "****************** FACE ID / V MIN: " << face_id << " / " << my_v_min << endl;
909 if (my_u_max < uv[0]) {
911 // cout << "****************** FACE ID / U MAX: " << face_id << " / " << my_u_max << endl;
913 if (my_v_max < uv[1]) {
915 // cout << "****************** FACE ID / V MAX: " << face_id << " / " << my_v_max << endl;
919 if (FaceId2PythonSmp.count(face_id) != 0){
920 PyObject * pyresult = NULL;
921 PyObject* new_stderr = NULL;
922 assert(Py_IsInitialized());
923 PyGILState_STATE gstate;
924 gstate = PyGILState_Ensure();
925 pyresult = PyObject_CallFunction(FaceId2PythonSmp[face_id],"(f,f)",uv[0],uv[1]);
927 if ( pyresult == NULL){
929 string err_description="";
930 new_stderr = newPyStdOut(err_description);
931 PySys_SetObject("stderr", new_stderr);
933 PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
934 Py_DECREF(new_stderr);
935 std::cout << "Can't evaluate f(" << uv[0] << "," << uv[1] << ")" << " error is " << err_description << std::endl;
936 result = *((double*)user_data);
939 result = PyFloat_AsDouble(pyresult);
943 //std::cout << "f(" << uv[0] << "," << uv[1] << ")" << " = " << result << std::endl;
944 PyGILState_Release(gstate);
947 *size = *((double*)user_data);
952 status_t size_on_edge(integer edge_id, real t, real *size, void *user_data)
954 if (EdgeId2PythonSmp.count(edge_id) != 0){
955 PyObject * pyresult = NULL;
956 PyObject* new_stderr = NULL;
957 assert(Py_IsInitialized());
958 PyGILState_STATE gstate;
959 gstate = PyGILState_Ensure();
960 pyresult = PyObject_CallFunction(EdgeId2PythonSmp[edge_id],"(f)",t);
962 if ( pyresult == NULL){
964 string err_description="";
965 new_stderr = newPyStdOut(err_description);
966 PySys_SetObject("stderr", new_stderr);
968 PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
969 Py_DECREF(new_stderr);
970 std::cout << "Can't evaluate f(" << t << ")" << " error is " << err_description << std::endl;
971 result = *((double*)user_data);
974 result = PyFloat_AsDouble(pyresult);
978 PyGILState_Release(gstate);
981 *size = *((double*)user_data);
986 status_t size_on_vertex(integer point_id, real *size, void *user_data)
988 if (VertexId2PythonSmp.count(point_id) != 0){
989 PyObject * pyresult = NULL;
990 PyObject* new_stderr = NULL;
991 assert(Py_IsInitialized());
992 PyGILState_STATE gstate;
993 gstate = PyGILState_Ensure();
994 pyresult = PyObject_CallFunction(VertexId2PythonSmp[point_id],"");
996 if ( pyresult == NULL){
998 string err_description="";
999 new_stderr = newPyStdOut(err_description);
1000 PySys_SetObject("stderr", new_stderr);
1002 PySys_SetObject("stderr", PySys_GetObject("__stderr__"));
1003 Py_DECREF(new_stderr);
1004 std::cout << "Can't evaluate f()" << " error is " << err_description << std::endl;
1005 result = *((double*)user_data);
1008 result = PyFloat_AsDouble(pyresult);
1009 Py_DECREF(pyresult);
1012 PyGILState_Release(gstate);
1015 *size = *((double*)user_data);
1020 status_t message_callback(message_t *msg, void *user_data)
1022 integer errnumber = 0;
1024 message_get_number(msg, &errnumber);
1025 message_get_description(msg, &desc);
1026 if ( errnumber < 0 ) {
1027 string * error = (string*)user_data;
1028 // if ( !error->empty() )
1030 // remove ^A from the tail
1031 int len = strlen( desc );
1032 while (len > 0 && desc[len-1] != '\n')
1034 error->append( desc, len );