From 4be31562cb6ecfacfea99a09553ab0c6bd79fdf4 Mon Sep 17 00:00:00 2001 From: Jean-Francois Remacle <jean-francois.remacle@uclouvain.be> Date: Wed, 12 May 2010 09:42:51 +0000 Subject: [PATCH] the solid modeler is now beginning to be usable : OCC : Pipes, NURBS, Constraint surfaces, planar surfaces, ruled surfaces are there The gluer is less bugged (yet not really usable) ACIS : interface is a little more complete brep IO's FIXED for OSX --- Common/Gmsh.cpp | 2 +- Geo/GFace.cpp | 82 ++++++++++++++++++ Geo/GModel.cpp | 48 ++++++++++- Geo/GModel.h | 4 + Geo/GModelFactory.cpp | 149 ++++++++++++++++++++++++++++++++- Geo/GModelFactory.h | 15 ++++ Geo/GModelIO_OCC.cpp | 22 ++++- Geo/GRegion.cpp | 5 ++ Geo/OCCRegion.cpp | 3 +- Solver/solverAlgorithms.h | 26 ++++++ benchmarks/boolean/square1.lua | 34 +++++++- 11 files changed, 375 insertions(+), 15 deletions(-) diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp index ed28f1559a..39be0d9578 100644 --- a/Common/Gmsh.cpp +++ b/Common/Gmsh.cpp @@ -167,7 +167,7 @@ int GmshBatch() GModel::current()->checkMeshCoherence(CTX::instance()->geom.tolerance); } else if(CTX::instance()->batch == -1){ - CreateOutputFile(CTX::instance()->outputFileName, FORMAT_GEO); + CreateOutputFile(CTX::instance()->outputFileName, FORMAT_AUTO); } else if(CTX::instance()->batch > 0){ #if defined(HAVE_MESH) diff --git a/Geo/GFace.cpp b/Geo/GFace.cpp index 6e2174bcce..f1572a01fa 100644 --- a/Geo/GFace.cpp +++ b/Geo/GFace.cpp @@ -484,6 +484,88 @@ end: } } +void computeMeanPlane(const std::vector<SPoint3> &points, mean_plane &meanPlane) +{ + double xm = 0., ym = 0., zm = 0.; + int ndata = points.size(); + int na = 3; + for(int i = 0; i < ndata; i++) { + xm += points[i].x(); + ym += points[i].y(); + zm += points[i].z(); + } + xm /= (double)ndata; + ym /= (double)ndata; + zm /= (double)ndata; + + fullMatrix<double> U(ndata, na), V(na, na); + fullVector<double> sigma(na); + for(int i = 0; i < ndata; i++) { + U(i, 0) = points[i].x() - xm; + U(i, 1) = points[i].y() - ym; + U(i, 2) = points[i].z() - zm; + } + U.svd(V, sigma); + double res[4], svd[3]; + svd[0] = sigma(0); + svd[1] = sigma(1); + svd[2] = sigma(2); + int min; + if(fabs(svd[0]) < fabs(svd[1]) && fabs(svd[0]) < fabs(svd[2])) + min = 0; + else if(fabs(svd[1]) < fabs(svd[0]) && fabs(svd[1]) < fabs(svd[2])) + min = 1; + else + min = 2; + res[0] = V(0, min); + res[1] = V(1, min); + res[2] = V(2, min); + norme(res); + + double ex[3], t1[3], t2[3]; + + ex[0] = ex[1] = ex[2] = 0.0; + if(res[0] == 0.) + ex[0] = 1.0; + else if(res[1] == 0.) + ex[1] = 1.0; + else + ex[2] = 1.0; + + prodve(res, ex, t1); + norme(t1); + prodve(t1, res, t2); + norme(t2); + + res[3] = (xm * res[0] + ym * res[1] + zm * res[2]); + + for(int i = 0; i < 3; i++) + meanPlane.plan[0][i] = t1[i]; + for(int i = 0; i < 3; i++) + meanPlane.plan[1][i] = t2[i]; + for(int i = 0; i < 3; i++) + meanPlane.plan[2][i] = res[i]; + + meanPlane.a = res[0]; + meanPlane.b = res[1]; + meanPlane.c = res[2]; + meanPlane.d = res[3]; + + meanPlane.x = meanPlane.y = meanPlane.z = 0.; + if(fabs(meanPlane.a) >= fabs(meanPlane.b) && + fabs(meanPlane.a) >= fabs(meanPlane.c) ){ + meanPlane.x = meanPlane.d / meanPlane.a; + } + else if(fabs(meanPlane.b) >= fabs(meanPlane.a) && + fabs(meanPlane.b) >= fabs(meanPlane.c)){ + meanPlane.y = meanPlane.d / meanPlane.b; + } + else{ + meanPlane.z = meanPlane.d / meanPlane.c; + } +} + + void GFace::getMeanPlaneData(double VX[3], double VY[3], double &x, double &y, double &z) const { diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp index fc92ff85db..2b873a0a60 100644 --- a/Geo/GModel.cpp +++ b/Geo/GModel.cpp @@ -1470,6 +1470,23 @@ GEdge *GModel::addNURBS(GVertex *start, GVertex *end, return 0; } +void GModel::addRuledFaces (std::vector<std::vector<GEdge *> > edges){ + if(_factory) + _factory->addRuledFaces(this, edges); +} + +GFace* GModel::addFace (std::vector<GEdge *> edges, std::vector< std::vector<double > > points){ + if(_factory) + return _factory->addFace(this, edges, points); + return 0; +} + +GFace* GModel::addPlanarFace (std::vector<std::vector<GEdge *> > edges){ + if(_factory) + return _factory->addPlanarFace(this, edges); + return 0; +} + GEntity *GModel::revolve(GEntity *e, std::vector<double> p1, std::vector<double> p2, double angle) { @@ -1484,6 +1501,12 @@ GEntity *GModel::extrude(GEntity *e, std::vector<double> p1, std::vector<double> return _factory->extrude(this, e, p1, p2); return 0; } +GEntity *GModel::addPipe(GEntity *e, std::vector<GEdge *> edges){ + if(_factory) + return _factory->addPipe(this,e,edges); + return 0; +} + GEntity *GModel::addSphere(double cx, double cy, double cz, double radius) { @@ -1735,7 +1758,12 @@ static void glueFacesInRegions(GModel *model, bool aDifferenceExists = false; std::list<GFace*> old = r->faces(), fnew; for (std::list<GFace*>::iterator fit = old.begin(); fit != old.end(); fit++){ - GFace *temp = Duplicates2Unique[*fit]; + std::map<GFace*, GFace*>::iterator itR = Duplicates2Unique.find(*fit); + if (itR == Duplicates2Unique.end()) + { + Msg::Fatal("error in the gluing process"); + } + GFace *temp = itR->second;; fnew.push_back(temp); if (temp != *fit){ aDifferenceExists = true; @@ -1834,6 +1862,18 @@ void GModel::registerBindings(binding *b) cm = cb->addMethod("addNURBS", &GModel::addNURBS); cm->setDescription("creates a NURBS curve from v1 to v2 with control Points, knots, weights and multiplicities"); cm->setArgNames("v1", "v2", "{{poles}}","{knots}","{weights}","{mult}",NULL); + cm = cb->addMethod("addFace", &GModel::addFace); + cm->setDescription("creates a face that is constraint by edges and points"); + cm->setArgNames("{list of edges}","{{x,y,z},{x,y,z},...}",NULL); + cm = cb->addMethod("addRuledFaces", &GModel::addRuledFaces); + cm->setDescription("creates ruled faces that contains a list of wires"); + cm->setArgNames("{{list of edges},{list of edges},...}",NULL); + cm = cb->addMethod("addPlanarFace", &GModel::addPlanarFace); + cm->setDescription("creates a planar face that contains a list of wires"); + cm->setArgNames("{{list of edges},{list of edges},...}",NULL); + cm = cb->addMethod("addPipe", &GModel::addPipe); + cm->setDescription("creates a pipe with a base and a wire for the direction"); + cm->setArgNames("ge","{list of edges}",NULL); cm = cb->addMethod("addCircleArcCenter", &GModel::addCircleArcCenter); cm->setDescription("create a circle arc going from v1 to v2 with its center " "at (x,y,z)"); @@ -1878,9 +1918,9 @@ void GModel::registerBindings(binding *b) "one (tool). The third parameter tells if a new model has to " "be created"); cm->setArgNames("tool","createNewGModel",NULL); - // cm = cb->addMethod("glue", &GModel::glue); - // cm->setDescription("glue the geometric model using geometric tolerance eps"); - // cm->setArgNames("eps",NULL); + cm = cb->addMethod("glue", &GModel::glue); + cm->setDescription("glue the geometric model using geometric tolerance eps"); + cm->setArgNames("eps",NULL); cm = cb->addMethod("setAsCurrent", &GModel::setAsCurrent); cm->setDescription("set the model as the current (active) one"); cm = cb->setConstructor<GModel>(); diff --git a/Geo/GModel.h b/Geo/GModel.h index 4c2fb7463d..8d48df7e76 100644 --- a/Geo/GModel.h +++ b/Geo/GModel.h @@ -376,6 +376,10 @@ class GModel GEntity *revolve(GEntity *e, std::vector<double> p1, std::vector<double> p2, double angle); GEntity *extrude(GEntity *e, std::vector<double> p1, std::vector<double> p2); + GEntity *addPipe(GEntity *e, std::vector<GEdge *> edges); + void addRuledFaces (std::vector<std::vector<GEdge *> > edges); + GFace* addFace (std::vector<GEdge *> edges, std::vector< std::vector<double > > points); + GFace* addPlanarFace (std::vector<std::vector<GEdge *> > edges); // create solid geometry primitives using the factory GEntity *addSphere(double cx, double cy, double cz, double radius); diff --git a/Geo/GModelFactory.cpp b/Geo/GModelFactory.cpp index 559590e8af..ac016c4fb7 100644 --- a/Geo/GModelFactory.cpp +++ b/Geo/GModelFactory.cpp @@ -11,11 +11,17 @@ #include "GModelIO_OCC.h" #include "OCCVertex.h" #include "OCCEdge.h" +#include "OCCFace.h" #include "OCCRegion.h" #include "BRepBuilderAPI_MakeVertex.hxx" +#include "BRepOffsetAPI_MakePipe.hxx" #include "BRepBuilderAPI_MakeEdge.hxx" #include "BRepPrimAPI_MakeRevol.hxx" #include "BRepPrimAPI_MakePrism.hxx" +#include "BRepBuilderAPI_MakeWire.hxx" +#include "BRepOffsetAPI_ThruSections.hxx" +#include "BRepOffsetAPI_MakeFilling.hxx" +#include "BRepBuilderAPI_MakeFace.hxx" #include <GC_MakeArcOfCircle.hxx> #include <gp_Pnt.hxx> #include <gp_Vec.hxx> @@ -170,8 +176,8 @@ GEdge *OCCFactory::addNURBS(GModel *gm, GVertex *start, GVertex *end, } const int degree = totKnots - nbControlPoints - 1; - printf("creation of a nurbs of degree %d with %d control points\n", - degree,nbControlPoints); + Msg::Debug("creation of a nurbs of degree %d with %d control points", + degree,nbControlPoints); int index = 1; ctrlPoints.SetValue(index++, gp_Pnt(start->x(), start->y(), start->z())); @@ -544,4 +550,143 @@ void OCCFactory::rotate(GModel *gm, std::vector<double> p1,std::vector<double> p gm->_occ_internals->buildGModel(gm); } + +std::vector<GFace *> OCCFactory::addRuledFaces (GModel *gm, std::vector< std::vector<GEdge *> > wires){ + + std::vector<GFace*> faces; + Standard_Boolean anIsSolid = Standard_False; + Standard_Boolean anIsRuled = Standard_True; + BRepOffsetAPI_ThruSections aGenerator (anIsSolid,anIsRuled); + + for (int i=0;i<wires.size();i++) { + BRepBuilderAPI_MakeWire wire_maker; + for (int j=0;j<wires[i].size();j++) { + GEdge *ge = wires[i][j]; + printf("edge %d\n",ge->tag()); + OCCEdge *occe = dynamic_cast<OCCEdge*>(ge); + if (occe){ + wire_maker.Add(occe->getTopoDS_Edge()); + } + } + aGenerator.AddWire (wire_maker.Wire()); + } + + aGenerator.CheckCompatibility (Standard_False); + + aGenerator.Build(); + + TopoDS_Shape aResult = aGenerator.Shape(); + + TopExp_Explorer exp2; + for(exp2.Init(TopoDS::Shell(aResult), TopAbs_FACE); exp2.More(); exp2.Next()){ + TopoDS_Face face = TopoDS::Face(exp2.Current()); + GFace *ret = gm->_occ_internals->addFaceToModel(gm, face); + faces.push_back(ret); + } + return faces; +} + +GFace * OCCFactory::addFace (GModel *gm, std::vector<GEdge *> edges, std::vector< std::vector<double > > points){ + + BRepOffsetAPI_MakeFilling aGenerator; + + for (int i=0;i<edges.size();i++) { + GEdge *ge = edges[i]; + OCCEdge *occe = dynamic_cast<OCCEdge*>(ge); + if (occe){ + aGenerator.Add(occe->getTopoDS_Edge(),GeomAbs_C0); + } + } + for (int i=0;i<points.size();i++) { + gp_Pnt aPnt (points[i][0],points[i][1],points[i][2]); + aGenerator.Add(aPnt); + } + + aGenerator.Build(); + + TopoDS_Shape aResult = aGenerator.Shape(); + return gm->_occ_internals->addFaceToModel(gm, TopoDS::Face(aResult)); +} + +extern void computeMeanPlane(const std::vector<SPoint3> &points, mean_plane &meanPlane); + +GFace * OCCFactory::addPlanarFace (GModel *gm, std::vector< std::vector<GEdge *> > wires){ + + std::set<GVertex*> verts; + for (int i=0;i<wires.size();i++) { + for (int j=0;j<wires[i].size();j++) { + GEdge *ge = wires[i][j]; + verts.insert(ge->getBeginVertex()); + verts.insert(ge->getEndVertex()); + } + } + std::vector<SPoint3> points; + std::set<GVertex*>::iterator it = verts.begin(); + for ( ; it != verts.end(); ++it){ + points.push_back(SPoint3((*it)->x(),(*it)->y(),(*it)->z())); + } + mean_plane meanPlane; + computeMeanPlane(points, meanPlane); + + gp_Pln aPlane (meanPlane.a,meanPlane.b,meanPlane.c,meanPlane.d); + BRepBuilderAPI_MakeFace aGenerator (aPlane); + + for (int i=0;i<wires.size();i++) { + BRepBuilderAPI_MakeWire wire_maker; + for (int j=0;j<wires[i].size();j++) { + GEdge *ge = wires[i][j]; + OCCEdge *occe = dynamic_cast<OCCEdge*>(ge); + if (occe){ + wire_maker.Add(occe->getTopoDS_Edge()); + } + } + TopoDS_Wire myWire = wire_maker.Wire(); + if (i)myWire.Reverse(); + aGenerator.Add (myWire); + } + + aGenerator.Build(); + + TopoDS_Shape aResult = aGenerator.Shape(); + return gm->_occ_internals->addFaceToModel(gm, TopoDS::Face(aResult)); +} + +GEntity * OCCFactory::addPipe (GModel *gm, GEntity *base, std::vector<GEdge *> wire){ + + BRepBuilderAPI_MakeWire wire_maker; + for (int j=0;j<wire.size();j++) { + GEdge *ge = wire[j]; + OCCEdge *occe = dynamic_cast<OCCEdge*>(ge); + if (occe){ + wire_maker.Add(occe->getTopoDS_Edge()); + } + } + TopoDS_Wire myWire = wire_maker.Wire(); + + + GEntity *ret; + if (base->cast2Vertex()){ + OCCVertex *occv = dynamic_cast<OCCVertex*>(base); + BRepOffsetAPI_MakePipe myNiceLittlePipe (myWire,occv->getShape()); + TopoDS_Edge result = TopoDS::Edge(myNiceLittlePipe.Shape()); + ret = gm->_occ_internals->addEdgeToModel(gm, result); + } + if (base->cast2Edge()){ + OCCEdge *occe = dynamic_cast<OCCEdge*>(base); + BRepOffsetAPI_MakePipe myNiceLittlePipe (myWire,occe->getTopoDS_Edge()); + TopoDS_Face result = TopoDS::Face(myNiceLittlePipe.Shape()); + ret = gm->_occ_internals->addFaceToModel(gm, result); + } + if (base->cast2Face()){ + OCCFace *occf = dynamic_cast<OCCFace*>(base); + BRepOffsetAPI_MakePipe myNiceLittlePipe (myWire,occf->getTopoDS_Face()); + TopoDS_Solid result = TopoDS::Solid(myNiceLittlePipe.Shape()); + ret = gm->_occ_internals->addRegionToModel(gm, result); + } + return ret; +} + + + + #endif diff --git a/Geo/GModelFactory.h b/Geo/GModelFactory.h index cad242d024..ae3f340e0e 100644 --- a/Geo/GModelFactory.h +++ b/Geo/GModelFactory.h @@ -25,8 +25,10 @@ class GModelFactory { // brep primitives enum arcCreationMethod {THREE_POINTS=1, CENTER_START_END=2}; enum splineType {BEZIER=1, BSPLINE=2}; + // vertex primitive virtual GVertex *addVertex(GModel *gm, double x, double y, double z, double lc) = 0; + // edge primitives virtual GEdge *addLine(GModel *, GVertex *v1, GVertex *v2) = 0; virtual GEdge *addCircleArc(GModel *gm, const arcCreationMethod &method, GVertex *start, GVertex *end, @@ -40,10 +42,19 @@ class GModelFactory { std::vector<double> knots, std::vector<double> weights, std::vector<int> multiplicity) = 0; + // faces primitives + // this one tries to build a model face with one single list + // of faces. If boundaries are co-planar, then it's a plane, + // otherwise, we tru ruled, sweep or other kind of surfaces + virtual std::vector<GFace *> addRuledFaces (GModel *gm, std::vector<std::vector<GEdge *> > edges) = 0; + virtual GFace * addFace (GModel *gm, std::vector<GEdge *> edges, std::vector< std::vector<double > > points) = 0; + virtual GFace * addPlanarFace (GModel *gm, std::vector<std::vector<GEdge *> > edges) = 0; + // sweep stuff virtual GEntity *revolve(GModel *gm, GEntity*, std::vector<double> p1, std::vector<double> p2, double angle) = 0; virtual GEntity *extrude(GModel *gm, GEntity*, std::vector<double> p1, std::vector<double> p2) = 0; + virtual GEntity* addPipe (GModel *gm, GEntity *base, std::vector<GEdge *> wire) = 0; // solid primitives virtual GEntity *addSphere(GModel *gm, double cx, double cy, double cz, @@ -99,9 +110,13 @@ class OCCFactory : public GModelFactory { std::vector<double> p2, double angle); GEntity *extrude (GModel *gm, GEntity*,std::vector<double> p1, std::vector<double> p2); + GEntity* addPipe (GModel *gm, GEntity *base, std::vector<GEdge *> wire); GEntity *addSphere(GModel *gm,double cx, double cy, double cz, double radius); GEntity *addCylinder(GModel *gm,std::vector<double> p1, std::vector<double> p2, double radius); + std::vector<GFace *> addRuledFaces (GModel *gm, std::vector<std::vector<GEdge *> > edges); + GFace * addFace (GModel *gm, std::vector<GEdge *> edges, std::vector< std::vector<double > > points); + GFace * addPlanarFace (GModel *gm, std::vector<std::vector<GEdge *> > edges); GEntity *addTorus(GModel *gm,std::vector<double> p1, std::vector<double> p2, double radius1, double radius2); GEntity *addBlock(GModel *gm,std::vector<double> p1, std::vector<double> p2); diff --git a/Geo/GModelIO_OCC.cpp b/Geo/GModelIO_OCC.cpp index 05dac36895..2072897494 100644 --- a/Geo/GModelIO_OCC.cpp +++ b/Geo/GModelIO_OCC.cpp @@ -36,7 +36,6 @@ void OCC_Internals::buildShapeFromLists(TopoDS_Shape _shape) BRep_Builder B; TopoDS_Compound C; B.MakeCompound(C); - // B.Add(C,_shape); TopTools_ListOfShape theList; addSimpleShapes(_shape, theList); @@ -45,9 +44,12 @@ void OCC_Internals::buildShapeFromLists(TopoDS_Shape _shape) for(int i = 1; i <= vmap.Extent(); i++) B.Add(C, vmap(i)); for(int i = 1; i <= emap.Extent(); i++) B.Add(C, emap(i)); + for(int i = 1; i <= wmap.Extent(); i++) B.Add(C, wmap(i)); for(int i = 1; i <= fmap.Extent(); i++) B.Add(C, fmap(i)); + for(int i = 1; i <= shmap.Extent(); i++) B.Add(C, shmap(i)); for(int i = 1; i <= somap.Extent(); i++) B.Add(C, somap(i)); shape = C; + } const TopoDS_Shape *OCC_Internals::lookupInLists(TopoDS_Shape _shape) @@ -413,7 +415,15 @@ void OCC_Internals::loadBREP(const char *fn) void OCC_Internals::writeBREP(const char *fn) { - BRepTools::Write(shape, (char*)fn); + std::ofstream myFile; + myFile.open (fn); + try { + BRepTools::Write(shape, myFile); + } + catch(Standard_Failure &err){ + Msg::Error("%s", err.GetMessageString()); + } + myFile.close (); } void OCC_Internals::loadSTEP(const char *fn) @@ -472,6 +482,8 @@ GVertex *OCC_Internals::addVertexToModel(GModel *model, TopoDS_Vertex vertex) GVertex *gv = getOCCVertexByNativePtr(model, vertex); if (gv) return gv; addShapeToLists(vertex); + buildShapeFromLists(vertex); + // buildLists(); buildGModel(model); return getOCCVertexByNativePtr (model,vertex); } @@ -481,6 +493,8 @@ GEdge *OCC_Internals::addEdgeToModel(GModel *model, TopoDS_Edge edge) GEdge *ge = getOCCEdgeByNativePtr(model, edge); if (ge) return ge; addShapeToLists(edge); + buildShapeFromLists(edge); + // buildLists(); buildGModel(model); return getOCCEdgeByNativePtr(model,edge); } @@ -489,6 +503,8 @@ GFace* OCC_Internals::addFaceToModel(GModel *model, TopoDS_Face face){ GFace *gf = getOCCFaceByNativePtr(model,face); if (gf) return gf; addShapeToLists(face); + buildShapeFromLists(face); + // buildLists(); buildGModel(model); return getOCCFaceByNativePtr(model,face); } @@ -498,6 +514,8 @@ GRegion* OCC_Internals::addRegionToModel(GModel *model, TopoDS_Solid region){ GRegion *gr = getOCCRegionByNativePtr(model,region); if (gr) return gr; addShapeToLists(region); + buildShapeFromLists(region); + //buildLists(); // buildLists(); // TEST buildGModel(model); diff --git a/Geo/GRegion.cpp b/Geo/GRegion.cpp index 9bd1539211..fa0c64346b 100644 --- a/Geo/GRegion.cpp +++ b/Geo/GRegion.cpp @@ -265,6 +265,11 @@ bool GRegion::edgeConnected(GRegion *r) const void GRegion::replaceFaces (std::list<GFace*> &new_faces) { replaceFacesInternal (new_faces); + if (l_faces.size() != new_faces.size()){ + Msg::Fatal("impossible to replace faces in region %d (%d vs %d)",tag(), + l_faces.size(),new_faces.size()); + } + std::list<GFace*>::iterator it = l_faces.begin(); std::list<GFace*>::iterator it2 = new_faces.begin(); std::list<int>::iterator it3 = l_dirs.begin(); diff --git a/Geo/OCCRegion.cpp b/Geo/OCCRegion.cpp index 946da65ffe..5a1dff017d 100644 --- a/Geo/OCCRegion.cpp +++ b/Geo/OCCRegion.cpp @@ -23,6 +23,7 @@ OCCRegion::OCCRegion(GModel *m, TopoDS_Solid _s, int num) void OCCRegion::setup() { + l_faces.clear(); TopExp_Explorer exp2, exp3; for(exp2.Init(s, TopAbs_SHELL); exp2.More(); exp2.Next()){ TopoDS_Shape shell = exp2.Current(); @@ -57,8 +58,6 @@ bool FaceHaveDifferentOrientations(const TopoDS_Face& aFR, void OCCRegion::replaceFacesInternal(std::list<GFace*> &new_faces) { // we simply replace old faces by new faces in the structure - Standard_Integer aNbS; - TopTools_IndexedMapOfShape aMS; TopExp_Explorer aExpS, aExpF; BRep_Builder aBB; TopoDS_Compound aCmp; diff --git a/Solver/solverAlgorithms.h b/Solver/solverAlgorithms.h index a7f3f43e68..ac501538e7 100644 --- a/Solver/solverAlgorithms.h +++ b/Solver/solverAlgorithms.h @@ -38,6 +38,32 @@ template<class Iterator,class Assembler> void Assemble(BilinearTermBase &term,Fu } } +template<class Iterator,class Assembler> void Assemble(BilinearTermBase &term, + FunctionSpaceBase &shapeFcts, + FunctionSpaceBase &testFcts, + Iterator itbegin, + Iterator itend, + QuadratureBase &integrator, + Assembler &assembler) // non symmetric +{ + fullMatrix<typename Assembler::dataMat> localMatrix; + std::vector<Dof> R; + std::vector<Dof> C; + for (Iterator it = itbegin;it!=itend; ++it) + { + MElement *e = *it; + R.clear(); + C.clear(); + IntPt *GP; + int npts=integrator.getIntPoints(e,&GP); + term.get(e,npts,GP,localMatrix); + shapeFcts.getKeys(e,R); + testFcts.getKeys(e,C); + assembler.assemble(R, C, localMatrix); + } +} + + template<class Assembler> void Assemble(BilinearTermBase &term,FunctionSpaceBase &space,MElement *e,QuadratureBase &integrator,Assembler &assembler) // symmetric { fullMatrix<typename Assembler::dataMat> localMatrix; diff --git a/benchmarks/boolean/square1.lua b/benchmarks/boolean/square1.lua index e9619fc833..a5a277a971 100644 --- a/benchmarks/boolean/square1.lua +++ b/benchmarks/boolean/square1.lua @@ -1,10 +1,36 @@ g = GModel() -v1 = g:addVertex(0, 0, 0, 1) -v2 = g:addVertex(1, 0, 0, 1) -v3 = g:addVertex(1, 1, 0, 1) -v4 = g:addVertex(0, 1, 0, 1) +v1 = g:addVertex(0, 0, 0, .1) +v2 = g:addVertex(1, 0, 0, .1) +v3 = g:addVertex(1, 1, 0, .1) +v4 = g:addVertex(0, 1, 0, .1) e1 = g:addLine(v1, v2) e2 = g:addLine(v2, v3) e3 = g:addLine(v3, v4) e4 = g:addLine(v4, v1) +v11 = g:addVertex(.4, .4, 0, .1) +v12 = g:addVertex(.5, .4, 0, .1) +v13 = g:addVertex(.5, .5, 0, .1) +v14 = g:addVertex(.4, .5, 0, .1) +e11 = g:addLine(v11, v12) +e12 = g:addLine(v12, v13) +e13 = g:addLine(v13, v14) +e14 = g:addLine(v14, v11) +f = g:addPlanarFace ({{e1,e2,e3,e4},{e11,e12,e13,e14}}) + +v100 = g:addVertex(0, 0, 0, .1) +v200 = g:addVertex(0, 0, 1, .1) +v300 = g:addVertex(0, .1, .33, .1) +v400 = g:addVertex(.1, .1, .66, .1) +line = g:addBezier(v100,v200,{{v300:x(),v300:y(),v300:z()},{v400:x(),v400:y(),v400:z()}}); +g:addPipe (f, {line}) + +g:glue(1.e-9); + +myTool = GModel(); +myTool:addSphere(0.2,0.2,0.1,.52012); + +--g:addSphere(1,1.3,1,.3); +g:computeDifference(myTool,0); + +g:setAsCurrent(); -- GitLab