static int gMousePick() { int index = -1; float minDist = DINGUS_BIG_FLOAT; // go through all meshes int i; int n = gEntities.size(); for( i = 0; i < n; ++i ) { const SVector3& p = gEntities[i]->mWorldMat.getOrigin(); const CAABox& aabb = gEntities[i]->getAABB(); float radius = SVector3(aabb.getMax() - aabb.getMin()).length() * 0.4f; if( gMouseRay.project( p ) < 0.0f ) continue; if( gMouseRay.distance( p ) > radius ) continue; float dist2 = SVector3(p-gMouseRay.pos).lengthSq(); if( dist2 < minDist ) { index = i; minDist = dist2; } } return index; }
// returns the cross field as a pair of othogonal vectors (NOT in parametric coordinates, but real 3D coordinates) Pair<SVector3, SVector3> frameFieldBackgroundMesh2D::compute_crossfield_directions(double u, double v, double angle_current) { // get the unit normal at that point GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return Pair<SVector3,SVector3>(SVector3(), SVector3()); } Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v)); SVector3 s1 = der.first(); SVector3 s2 = der.second(); SVector3 n = crossprod(s1,s2); n.normalize(); SVector3 basis_u = s1; basis_u.normalize(); SVector3 basis_v = crossprod(n,basis_u); // normalize vector t1 that is tangent to gf at uv SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ; t1.normalize(); // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame SVector3 t2 = crossprod(n,t1); t2.normalize(); return Pair<SVector3,SVector3>(SVector3(t1[0],t1[1],t1[2]), SVector3(t2[0],t2[1],t2[2])); }
Metric Filler::get_metric(double x,double y,double z,GEntity* ge){ Metric m; SMetric3 temp; SVector3 v1,v2,v3; Field* field; FieldManager* manager; v1 = SVector3(1.0,0.0,0.0); v2 = SVector3(0.0,1.0,0.0); v3 = SVector3(0.0,0.0,1.0); manager = ge->model()->getFields(); if(manager->getBackgroundField()>0){ field = manager->get(manager->getBackgroundField()); if(field){ (*field)(x,y,z,temp,ge); } } m.set_m11(v1.x()); m.set_m21(v1.y()); m.set_m31(v1.z()); m.set_m12(v2.x()); m.set_m22(v2.y()); m.set_m32(v2.z()); m.set_m13(v3.x()); m.set_m23(v3.y()); m.set_m33(v3.z()); return m; }
SOrientedBoundingBox::SOrientedBoundingBox() { center = SVector3(); size = SVector3(); axisX = SVector3(); axisY = SVector3(); axisZ = SVector3(); fillp(); }
Player::Player(SVector3* pos, SVector3* vel, CMesh* mod, float size) : GameObject(pos, vel, mod) { health = 100; cooldown = 0; firing = false; this->size = size; Translation.X = pos->X; Translation.Y = pos->Y; Translation.Z = pos->Z; Scale.X = 1; Scale.Y = 1; Scale.Z = 1; Rotation.X = 90; Rotation.Y = 0; Rotation.Z = 0; // First create a shader loader and check if our hardware supports shaders CShaderLoader ShaderLoader; if (! ShaderLoader.isValid()) { std::cerr << "Shaders are not supported by your graphics hardware, or the shader loader was otherwise unable to load." << std::endl; waitForUser3(); } // Now attempt to load the shaders shade = ShaderLoader.loadShader("Shaders/GameVert2.glsl", "Shaders/Lab3_frag.glsl"); if (! shade) { std::cerr << "Unable to open or compile necessary shader." << std::endl; waitForUser3(); } shade->loadAttribute("aPosition"); shade->loadAttribute("aColor"); shade->loadAttribute("aNormal"); // Attempt to load mesh mod = CMeshLoader::loadASCIIMesh("Models/spaceship.obj"); //mod = CMeshLoader::loadASCIIMesh("Models/cessna_color500.m"); if (! mod) { std::cerr << "Unable to load necessary mesh." << std::endl; waitForUser3(); } // Make out mesh fit within camera view mod->resizeMesh(SVector3(1)); // And center it at the origin mod->centerMeshByExtents(SVector3(0)); // Now load our mesh into a VBO, retrieving the number of triangles and the handles to each VBO CMeshLoader::createVertexBufferObject(* mod, TriangleCount, PositionBufferHandle, ColorBufferHandle, NormalBufferHandle); }
SVector3 gmshFace::normal(const SPoint2 ¶m) const { if(s->Typ != MSH_SURF_PLAN){ Vertex vu = InterpolateSurface(s, param[0], param[1], 1, 1); Vertex vv = InterpolateSurface(s, param[0], param[1], 1, 2); Vertex n = vu % vv; n.norme(); return SVector3(n.Pos.X, n.Pos.Y, n.Pos.Z); } else{ // We cannot use InterpolateSurface() for plane surfaces since it // relies on the mean plane, which does not respect the // orientation // FIXME: move this test at the end of the MeanPlane computation // routine--and store the correct normal, damn it! double n[3] = {meanPlane.a, meanPlane.b, meanPlane.c}; norme(n); GPoint pt = point(param.x(), param.y()); double v[3] = {pt.x(), pt.y(), pt.z()}; int NP = 10, tries = 0; while(1){ tries++; double angle = 0.; for(int i = 0; i < List_Nbr(s->Generatrices); i++) { Curve *c; List_Read(s->Generatrices, i, &c); int N = (c->Typ == MSH_SEGM_LINE) ? 1 : NP; for(int j = 0; j < N; j++) { double u1 = (double)j / (double)N; double u2 = (double)(j + 1) / (double)N; Vertex p1 = InterpolateCurve(c, u1, 0); Vertex p2 = InterpolateCurve(c, u2, 0); double v1[3] = {p1.Pos.X, p1.Pos.Y, p1.Pos.Z}; double v2[3] = {p2.Pos.X, p2.Pos.Y, p2.Pos.Z}; angle += angle_plan(v, v1, v2, n); } } if(fabs(angle) < 0.5){ // we're outside NP *= 2; Msg::Debug("Could not compute normal of surface %d - retrying with %d points", tag(), NP); if(tries > 10){ Msg::Warning("Could not orient normal of surface %d", tag()); return SVector3(n[0], n[1], n[2]); } } else if(angle > 0) return SVector3(n[0], n[1], n[2]); else return SVector3(-n[0], -n[1], -n[2]); } } }
bool CMeshLoader::loadVertexBufferObjectFromMesh(std::string const & fileName, int & TriangleCount, GLuint & PositionBufferHandle, GLuint & ColorBufferHandle, GLuint & NormalBufferHandle) { CMesh * Mesh = loadASCIIMesh(fileName); if (! Mesh) return false; Mesh->resizeMesh(SVector3(1)); Mesh->centerMeshByExtents(SVector3(0)); Mesh->computeNormals(); createVertexBufferObject(* Mesh, TriangleCount, PositionBufferHandle, ColorBufferHandle, NormalBufferHandle); return true; }
Pair<SVector3, SVector3> gmshFace::firstDer(const SPoint2 ¶m) const { if(s->Typ == MSH_SURF_PLAN && !s->geometry){ double x, y, z, VX[3], VY[3]; getMeanPlaneData(VX, VY, x, y, z); return Pair<SVector3, SVector3>(SVector3(VX[0], VX[1], VX[2]), SVector3(VY[0], VY[1], VY[2])); } else{ Vertex vu = InterpolateSurface(s, param[0], param[1], 1, 1); Vertex vv = InterpolateSurface(s, param[0], param[1], 1, 2); return Pair<SVector3, SVector3>(SVector3(vu.Pos.X, vu.Pos.Y, vu.Pos.Z), SVector3(vv.Pos.X, vv.Pos.Y, vv.Pos.Z)); } }
void CWall3D::fracturePiecesInYRange( float t, float y1, float y2, TIntVector& pcs ) { if( !mPiecesInited ) initPieces(); // fetch the pieces pcs.resize( 0 ); // TODO: optimize, right now linear search! float pieceRestoreTime = t + 1.0e6f; int n = mWall2D.getPieceCount(); for( int i = 0; i < n; ++i ) { const CWallPiece2D& p = mWall2D.getPiece( i ); SVector2 c = p.getAABB().getCenter(); float y = c.y; if( mMatrix.getAxisY().y < 0.5f ) { SVector3 wc; D3DXVec3TransformCoord( &wc, &SVector3(c.x,c.y,0), &mMatrix ); y = wc.y; } if( y >= y1 && y <= y2 ) { mPieceRestoreTimes[i] = pieceRestoreTime; if( mFracturedPieces[i] ) continue; pcs.push_back( i ); fractureOutPiece( i ); } } }
SVector3 MFace::normal() const { double n[3]; normal3points(_v[0]->x(), _v[0]->y(), _v[0]->z(), _v[1]->x(), _v[1]->y(), _v[1]->z(), _v[2]->x(), _v[2]->y(), _v[2]->z(), n); return SVector3(n[0], n[1], n[2]); }
SVector3 OCCEdge::firstDer(double par) const { BRepAdaptor_Curve brepc(c); BRepLProp_CLProps prop(brepc, 1, 1e-5); prop.SetParameter(par); gp_Vec d1 = prop.D1(); return SVector3(d1.X(), d1.Y(), d1.Z()); }
SVector3 GEdgeCompound::firstDer(double par) const { double tLoc; int iEdge; if(!getLocalParameter(par, iEdge, tLoc)) return SVector3(); return _compound[iEdge]->firstDer(tLoc); }
int MZoneBoundary<DIM>::exteriorBoundaryVertices (const int normalSource, ZoneBoVec &zoneBoVec) { if(globalBoVertMap.size() == 0) return 1; zoneBoVec.clear(); zoneBoVec.reserve(3*globalBoVertMap.size()/2); BCPatchIndex patch; // Provides a BC patch index for each // entity bool warnNormFromElem = true; // A warning that normals were // determined from elements. This // warning is only give once (after // which the flag is set to false) const typename GlobalBoVertexMap::const_iterator vMapEnd = globalBoVertMap.end(); for(typename GlobalBoVertexMap::const_iterator vMapIt = globalBoVertMap.begin(); vMapIt != vMapEnd; ++vMapIt) { const int nZone = vMapIt->second.zoneData.size(); for(int iZone = 0; iZone != nZone; ++iZone) { const typename GlobalVertexData<FaceT>::ZoneData &zoneData = vMapIt->second.zoneData[iZone]; // Ref. to data stored for this zone //--Try to find an outwards normal for this vertex if(normalSource) { updateBoVec<DIM, FaceT>(normalSource, vMapIt->first, zoneData.zoneIndex, zoneData.vertexIndex, vMapIt->second.faces, zoneBoVec, patch, warnNormFromElem); } else { // Keys to 'globalBoVertMap' will not change so const_cast is okay. zoneBoVec.push_back(VertexBoundary(zoneData.zoneIndex, 0, SVector3(0.), const_cast<MVertex*>(vMapIt->first), zoneData.vertexIndex)); } } } // If normals were written from the geometry, zoneBoVec currently stores // entities in bcPatchIndex. Update with the actual patch index. Why? - // because two entities may have been merged if the interface between them is // continuous. if(normalSource == NormalSourceGeometry) { patch.generatePatchIndices(); const int nBoVert = zoneBoVec.size(); for(int iBoVert = 0; iBoVert != nBoVert; ++iBoVert) { zoneBoVec[iBoVert].bcPatchIndex = patch.getIndex(zoneBoVec[iBoVert].bcPatchIndex); } } return 0; }
SMetric3 buildMetricTangentToCurve(SVector3 &t, double l_t, double l_n) { if (l_t == 0.0) return SMetric3(1.e-22); SVector3 a; if (fabs(t(0)) <= fabs(t(1)) && fabs(t(0)) <= fabs(t(2))){ a = SVector3(1,0,0); } else if (fabs(t(1)) <= fabs(t(0)) && fabs(t(1)) <= fabs(t(2))){ a = SVector3(0,1,0); } else{ a = SVector3(0,0,1); } SVector3 b = crossprod (t,a); SVector3 c = crossprod (b,t); b.normalize(); c.normalize(); t.normalize(); SMetric3 Metric (1./(l_t*l_t),1./(l_n*l_n),1./(l_n*l_n),t,b,c); // printf("bmttc %g %g %g %g %g\n",l_t,l_n,Metric(0,0),Metric(0,1),Metric(1,1)); return Metric; }
void CMinimapRenderer::render() { // early out if no entities to render if( mEntities.empty() ) return; // stuff entities into vertex buffer int n = mEntities.size(); const int MAX_ENTITIES = 1000; // cap the max. entities if( n > MAX_ENTITIES ) n = MAX_ENTITIES; TVBChunk::TSharedPtr chunk = CDynamicVBManager::getInstance().allocateChunk( n*4, sizeof(TVertex) ); TVertex* vb = (TVertex*)chunk->getData(); for( int i = 0; i < n; ++i ) { const SEntity& e = mEntities[i]; vb[0].p = e.pos + SVector3(-e.size,0,-e.size); vb[0].diffuse = e.color; vb[0].tu = 0; vb[0].tv = 0; vb[1].p = e.pos + SVector3( e.size,0,-e.size); vb[1].diffuse = e.color; vb[1].tu = 1; vb[1].tv = 0; vb[2].p = e.pos + SVector3( e.size,0, e.size); vb[2].diffuse = e.color; vb[2].tu = 1; vb[2].tv = 1; vb[3].p = e.pos + SVector3(-e.size,0, e.size); vb[3].diffuse = e.color; vb[3].tu = 0; vb[3].tv = 1; vb += 4; } chunk->unlock(); // set onto renderable buffer and attach it mRenderable->resetVBs(); mRenderable->setVertexDecl( mVDecl ); mRenderable->setIB( *mIB ); mRenderable->setVB( chunk->getBuffer(), 0 ); mRenderable->setStride( chunk->getStride(), 0 ); mRenderable->setBaseVertex( chunk->getOffset() ); mRenderable->setMinVertex( 0 ); mRenderable->setNumVertices( chunk->getSize() ); mRenderable->setStartIndex( 0 ); mRenderable->setPrimCount( chunk->getSize()/2 ); mRenderable->setPrimType( D3DPT_TRIANGLELIST ); G_RENDERCTX->attach( *mRenderable ); }
static void computeGradSFAtNodes (MElement *e, std::vector<std::vector<SVector3> > &gsf) { const nodalBasis &elbasis = *e->getFunctionSpace(); double s[256][3]; for (int j=0;j<e->getNumVertices();j++){ std::vector<SVector3> g(e->getNumVertices()); double u_mesh = elbasis.points(j,0); double v_mesh = elbasis.points(j,1); e->getGradShapeFunctions ( u_mesh , v_mesh , 0, s); for (int k=0;k<e->getNumVertices();k++) g[k] = SVector3(s[k][0],s[k][1],s[k][2]); gsf.push_back(g); } }
void elasticitySolver::addNeumannBC (int dim, int entityId, const std::vector<double> value) { if(value.size()!=3) return; neumannBC neu; neu.g = new groupOfElements (dim, entityId); neu._f= new simpleFunction<SVector3>(SVector3(value[0], value[1], value[2])); neu._tag=entityId; switch (dim) { case 0 : neu.onWhat=BoundaryCondition::ON_VERTEX; break; case 1 : neu.onWhat=BoundaryCondition::ON_EDGE; break; case 2 : neu.onWhat=BoundaryCondition::ON_FACE; break; default : return; } allNeumann.push_back(neu); }
void Filler::create_spawns(GEntity* ge,MElementOctree* octree,Node* node,std::vector<Node*>& spawns){ double x,y,z; double x1,y1,z1; double x2,y2,z2; double x3,y3,z3; double x4,y4,z4; double x5,y5,z5; double x6,y6,z6; double h; double h1,h2,h3,h4,h5,h6; Metric m; SPoint3 point; point = node->get_point(); x = point.x(); y = point.y(); z = point.z(); h = node->get_size(); m = node->get_metric(); h1 = improvement(ge,octree,point,h,SVector3(m.get_m11(),m.get_m21(),m.get_m31())); x1 = x + h1*m.get_m11(); y1 = y + h1*m.get_m21(); z1 = z + h1*m.get_m31(); h2 = improvement(ge,octree,point,h,SVector3(-m.get_m11(),-m.get_m21(),-m.get_m31())); x2 = x - h2*m.get_m11(); y2 = y - h2*m.get_m21(); z2 = z - h2*m.get_m31(); h3 = improvement(ge,octree,point,h,SVector3(m.get_m12(),m.get_m22(),m.get_m32())); x3 = x + h3*m.get_m12(); y3 = y + h3*m.get_m22(); z3 = z + h3*m.get_m32(); h4 = improvement(ge,octree,point,h,SVector3(-m.get_m12(),-m.get_m22(),-m.get_m32())); x4 = x - h4*m.get_m12(); y4 = y - h4*m.get_m22(); z4 = z - h4*m.get_m32(); h5 = improvement(ge,octree,point,h,SVector3(m.get_m13(),m.get_m23(),m.get_m33())); x5 = x + h5*m.get_m13(); y5 = y + h5*m.get_m23(); z5 = z + h5*m.get_m33(); h6 = improvement(ge,octree,point,h,SVector3(-m.get_m13(),-m.get_m23(),-m.get_m33())); x6 = x - h6*m.get_m13(); y6 = y - h6*m.get_m23(); z6 = z - h6*m.get_m33(); *spawns[0] = Node(SPoint3(x1,y1,z1)); *spawns[1] = Node(SPoint3(x2,y2,z2)); *spawns[2] = Node(SPoint3(x3,y3,z3)); *spawns[3] = Node(SPoint3(x4,y4,z4)); *spawns[4] = Node(SPoint3(x5,y5,z5)); *spawns[5] = Node(SPoint3(x6,y6,z6)); }
SOrientedBoundingBox::SOrientedBoundingBox(SVector3 ¢er_, double sizeX, double sizeY, double sizeZ, const SVector3 &axisX_, const SVector3 &axisY_, const SVector3 &axisZ_) { center = center_; size = SVector3(sizeX, sizeY, sizeZ); axisX = axisX_; axisX.normalize(); axisY = axisY_; axisY.normalize(); axisZ = axisZ_; axisZ.normalize(); fillp(); }
int edge_normal (const MVertex *const vertex, const int zoneIndex, const GEdge *const gEdge, const CCon::FaceVector<MZoneBoundary<2>::GlobalVertexData<MEdge>::FaceDataB> &faces, SVector3 &boNormal, const int onlyFace = -1) { double par=0.0; // Note: const_cast used to match MVertex.cpp interface if(!reparamMeshVertexOnEdge(const_cast<MVertex*>(vertex), gEdge, par)) return 1; const SVector3 tangent(gEdge->firstDer(par)); // Tangent to the boundary face SPoint3 interior(0., 0., 0.); // An interior point SVector3 meshPlaneNormal(0.); // This normal is perpendicular to the // plane of the mesh // The interior point and mesh plane normal are computed from all elements in // the zone. int cFace = 0; int iFace = 0; int nFace = faces.size(); if ( onlyFace >= 0 ) { iFace = onlyFace; nFace = onlyFace + 1; } for(; iFace != nFace; ++iFace) { if(faces[iFace].zoneIndex == zoneIndex) { ++cFace; interior += faces[iFace].parentElement->barycenter(); // Make sure all the planes go in the same direction //**Required? SVector3 mpnt = faces[iFace].parentElement->getFace(0).normal(); if(dot(mpnt, meshPlaneNormal) < 0.) mpnt.negate(); meshPlaneNormal += mpnt; } } interior /= cFace; // Normal to the boundary edge (but unknown direction) boNormal = crossprod(tangent, meshPlaneNormal); boNormal.normalize(); // Direction vector from vertex to interior (inwards). The normal should // point in the same direction. if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.) boNormal.negate(); return 0; }
CMesh * const CMeshLoader::loadASCIIMesh(std::string const & fileName) { std::ifstream File; File.open(fileName.c_str()); if (! File.is_open()) { std::cerr << "Unable to open mesh file: " << fileName << std::endl; return 0; } CMesh * Mesh = new CMesh(); while (File) { std::string ReadString; std::getline(File, ReadString); std::stringstream Stream(ReadString); std::string Label; Stream >> Label; if (Label.find("#") != std::string::npos) { // Comment, skip continue; } if ("Vertex" == Label) { int Index; Stream >> Index; // We don't care, throw it away SVector3 Position; Stream >> Position.X; Stream >> Position.Y; Stream >> Position.Z; SVertex Vertex; Vertex.Position = Position; Vertex.Normal = SVector3(0); Mesh->Vertices.push_back(Vertex); } else if ("Face" == Label)
void ComputeInterestingSceneParts( const SVector3& lightDir, const SMatrix4x4& cameraViewProj ) { bool hit = false; SVector3 sweepDir = lightDir; // camera frustum Frustum sceneFrustum( cameraViewProj ); gSceneReceivers.clear(); gSceneCasters.clear(); gCasterBounds.setNull(); gReceiverBounds.setNull(); size_t n = gScene.size(); for( size_t i = 0; i < n; ++i ) { SceneEntity& obj = *gScene[i]; CAABox aabb = obj.getAABB(); aabb.transform( obj.mWorldMat ); if( aabb.frustumCull( cameraViewProj ) ) { SVector3 spherePos = aabb.getCenter(); float sphereRadius = SVector3(aabb.getMax()-aabb.getMin()).length() / 2; if( sceneFrustum.TestSweptSphere( spherePos, sphereRadius, sweepDir ) ) { hit = true; gSceneCasters.push_back( ObjectInfo(aabb,obj) ); // originally in view space gCasterBounds.extend( aabb ); } } else { hit = true; gSceneCasters.push_back( ObjectInfo(aabb,obj) ); // originally in view space gSceneReceivers.push_back( ObjectInfo(aabb,obj) ); // originally in view space gCasterBounds.extend( aabb ); gReceiverBounds.extend( aabb ); } } }
void gmshFace::secondDer(const SPoint2 ¶m, SVector3 *dudu, SVector3 *dvdv, SVector3 *dudv) const { if(s->Typ == MSH_SURF_PLAN && !s->geometry){ *dudu = SVector3(0., 0., 0.); *dvdv = SVector3(0., 0., 0.); *dudv = SVector3(0., 0., 0.); } else{ Vertex vuu = InterpolateSurface(s, param[0], param[1], 2, 1); Vertex vvv = InterpolateSurface(s, param[0], param[1], 2, 2); Vertex vuv = InterpolateSurface(s, param[0], param[1], 2, 3); *dudu = SVector3(vuu.Pos.X,vuu.Pos.Y,vuu.Pos.Z); *dvdv = SVector3(vvv.Pos.X,vvv.Pos.Y,vvv.Pos.Z); *dudv = SVector3(vuv.Pos.X,vuv.Pos.Y,vuv.Pos.Z); } }
int main(int argc,char *argv[]) { if(argc < 6){ printf("Usage: %s file lx ly lz rmax [levels=1] [refcs=1]\n", argv[0]); printf("where\n"); printf(" 'file' contains a CAD model\n"); printf(" 'lx', 'ly' and 'lz' are the sizes of the elements along the" " x-, y- and z-axis at the coarsest level\n"); printf(" 'rmax' is the radius of the largest sphere that can be inscribed" " in the structure\n"); printf(" 'levels' sets the number of levels in the grid\n"); printf(" 'refcs' selects if curved surfaces should be refined\n"); return -1; } GmshInitialize(); GmshSetOption("General", "Terminal", 1.); GmshMergeFile(argv[1]); double lx = atof(argv[2]), ly = atof(argv[3]), lz = atof(argv[4]); double rmax = atof(argv[5]); int levels = (argc > 6) ? atof(argv[6]) : 1; int refineCurvedSurfaces = (argc > 7) ? atof(argv[7]) : 1; // minimum distance between points in the cloud at the coarsest // level double sampling = std::min(rmax, std::min(lx, std::min(ly, lz))); // radius of the "tube" created around parts to refine at the // coarsest level double rtube = std::max(lx, std::max(ly, lz)) * 2.; GModel *gm = GModel::current(); std::vector<SPoint3> points; Msg::Info("Filling coarse point cloud on surfaces"); for (GModel::fiter fit = gm->firstFace(); fit != gm->lastFace(); fit++) (*fit)->fillPointCloud(sampling, &points); Msg::Info(" %d points in the surface cloud", (int)points.size()); std::vector<SPoint3> refinePoints; if(levels > 1){ double s = sampling / pow(2., levels - 1); Msg::Info("Filling refined point cloud on curves and curved surfaces"); for (GModel::eiter eit = gm->firstEdge(); eit != gm->lastEdge(); eit++) fillPointCloud(*eit, s, refinePoints); // FIXME: refine this by computing e.g. "mean" curvature if(refineCurvedSurfaces){ for (GModel::fiter fit = gm->firstFace(); fit != gm->lastFace(); fit++) if((*fit)->geomType() != GEntity::Plane) (*fit)->fillPointCloud(2 * s, &refinePoints); } Msg::Info(" %d points in the refined cloud", (int)refinePoints.size()); } SBoundingBox3d bb; for(unsigned int i = 0; i < points.size(); i++) bb += points[i]; for(unsigned int i = 0; i < refinePoints.size(); i++) bb += refinePoints[i]; bb.scale(1.21, 1.21, 1.21); SVector3 range = bb.max() - bb.min(); int NX = range.x() / lx; int NY = range.y() / ly; int NZ = range.z() / lz; if(NX < 2) NX = 2; if(NY < 2) NY = 2; if(NZ < 2) NZ = 2; Msg::Info(" bounding box min: %g %g %g -- max: %g %g %g", bb.min().x(), bb.min().y(), bb.min().z(), bb.max().x(), bb.max().y(), bb.max().z()); Msg::Info(" Nx=%d Ny=%d Nz=%d", NX, NY, NZ); cartesianBox<double> box(bb.min().x(), bb.min().y(), bb.min().z(), SVector3(range.x(), 0, 0), SVector3(0, range.y(), 0), SVector3(0, 0, range.z()), NX, NY, NZ, levels); Msg::Info("Inserting active cells in the cartesian grid"); Msg::Info(" level %d", box.getLevel()); for (unsigned int i = 0; i < points.size(); i++) insertActiveCells(points[i].x(), points[i].y(), points[i].z(), rmax, box); cartesianBox<double> *parent = &box, *child; while((child = parent->getChildBox())){ Msg::Info(" level %d", child->getLevel()); for(unsigned int i = 0; i < refinePoints.size(); i++) insertActiveCells(refinePoints[i].x(), refinePoints[i].y(), refinePoints[i].z(), rtube / pow(2., (levels - child->getLevel())), *child); parent = child; } // remove child cells that do not entirely fill parent cell or for // which there is no parent neighbor; then remove parent cells that // have children Msg::Info("Removing cells to match X-FEM mesh topology constraints"); removeBadChildCells(&box); removeParentCellsWithChildren(&box); // we generate duplicate nodes at this point so we can easily access // cell values at each level; we will clean up by renumbering after // filtering Msg::Info("Initializing nodal values in the cartesian grid"); box.createNodalValues(); Msg::Info("Computing levelset on the cartesian grid"); computeLevelset(gm, box); Msg::Info("Removing cells outside the structure"); removeOutsideCells(&box); Msg::Info("Renumbering mesh vertices across levels"); box.renumberNodes(); bool decomposeInSimplex = false; box.writeMSH("yeah.msh", decomposeInSimplex); Msg::Info("Done!"); GmshFinalize(); }
Enemy::Enemy (float random) { srand(random); Translation.X = rand() % 9 + 0.5; Translation.Y = 0.5; Translation.Z = rand() % 9 + 0.5; Scale.X = 1; Scale.Y = 1; Scale.Z = 1; Rotation.Z = 0; Rotation.X = 0; Rotation.Y = rand() % 360; alive = 1; size = 0.38; next = 0; // First create a shader loader and check if our hardware supports shaders CShaderLoader ShaderLoader; if (! ShaderLoader.isValid()) { std::cerr << "Shaders are not supported by your graphics hardware, or the shader loader was otherwise unable to load." << std::endl; waitForUser(); } // Now attempt to load the shaders Shader = ShaderLoader.loadShader("Shaders/Lab3_vert.glsl", "Shaders/Lab3_frag.glsl"); if (! Shader) { std::cerr << "Unable to open or compile necessary shader." << std::endl; waitForUser(); } Shader->loadAttribute("aPosition"); Shader->loadAttribute("aColor"); Shader->loadAttribute("aNormal"); // Now attempt to load the shaders Shader2 = ShaderLoader.loadShader("Shaders/Lab3_vert2.glsl", "Shaders/Lab3_frag.glsl"); if (! Shader2) { std::cerr << "Unable to open or compile necessary shader." << std::endl; waitForUser(); } Shader2->loadAttribute("aPosition"); Shader2->loadAttribute("aColor"); Shader2->loadAttribute("aNormal"); // Attempt to load mesh CMesh * Mesh = CMeshLoader::loadASCIIMesh("Models/gargoyle500.m"); if (! Mesh) { std::cerr << "Unable to load necessary mesh." << std::endl; waitForUser(); } // Make out mesh fit within camera view Mesh->resizeMesh(SVector3(1)); // And center it at the origin Mesh->centerMeshByExtents(SVector3(0)); // Now load our mesh into a VBO, retrieving the number of triangles and the handles to each VBO CMeshLoader::createVertexBufferObject(* Mesh, TriangleCount, PositionBufferHandle, ColorBufferHandle, NormalBufferHandle); }
void elasticitySolver::readInputFile(const std::string &fn) { FILE *f = Fopen(fn.c_str(), "r"); char what[256]; while(!feof(f)){ if(fscanf(f, "%s", what) != 1){ fclose(f); return; } if(what[0]=='#'){ /* char *line=NULL; size_t l = 0; int r = getline(&line,&l,f); free(line); */ } else if (!strcmp(what, "ElasticDomain")){ elasticField field; int physical; if(fscanf(f, "%d %lf %lf", &physical, &field._E, &field._nu) != 3){ fclose(f); return; } field._tag = _tag; field.g = new groupOfElements (_dim, physical); elasticFields.push_back(field); } else if (!strcmp(what, "LagrangeMultipliers")){ LagrangeMultiplierField field; int physical; double d1, d2, d3, val; if(fscanf(f, "%d %lf %lf %lf %lf %lf %d", &physical, &field._tau, &d1, &d2, &d3, &val, &field._tag) != 7){ fclose(f); return; } field._tag = _tag; field._d = SVector3(d1, d2, d3); field._f = simpleFunction<double>(val); field.g = new groupOfElements (_dim - 1, physical); LagrangeMultiplierFields.push_back(field); } else if (!strcmp(what, "Void")){ elasticField field; int physical; if(fscanf(f, "%d", &physical) != 1){ fclose(f); return; } field._E = field._nu = 0; field.g = new groupOfElements (_dim, physical); field._tag = 0; elasticFields.push_back(field); } else if (!strcmp(what, "NodeDisplacement")){ double val; int node, comp; if(fscanf(f, "%d %d %lf", &node, &comp, &val) != 3){ fclose(f); return; } dirichletBC diri; diri.g = new groupOfElements (0, node); diri._f= new simpleFunction<double>(val); diri._comp=comp; diri._tag=node; diri.onWhat=BoundaryCondition::ON_VERTEX; allDirichlet.push_back(diri); } else if (!strcmp(what, "EdgeDisplacement")){ double val; int edge, comp; if(fscanf(f, "%d %d %lf", &edge, &comp, &val) != 3){ fclose(f); return; } dirichletBC diri; diri.g = new groupOfElements (1, edge); diri._f= new simpleFunction<double>(val); diri._comp=comp; diri._tag=edge; diri.onWhat=BoundaryCondition::ON_EDGE; allDirichlet.push_back(diri); } else if (!strcmp(what, "FaceDisplacement")){ double val; int face, comp; if(fscanf(f, "%d %d %lf", &face, &comp, &val) != 3){ fclose(f); return; } dirichletBC diri; diri.g = new groupOfElements (2, face); diri._f= new simpleFunction<double>(val); diri._comp=comp; diri._tag=face; diri.onWhat=BoundaryCondition::ON_FACE; allDirichlet.push_back(diri); } else if (!strcmp(what, "NodeForce")){ double val1, val2, val3; int node; if(fscanf(f, "%d %lf %lf %lf", &node, &val1, &val2, &val3) != 4){ fclose(f); return; } neumannBC neu; neu.g = new groupOfElements (0, node); neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3)); neu._tag=node; neu.onWhat=BoundaryCondition::ON_VERTEX; allNeumann.push_back(neu); } else if (!strcmp(what, "EdgeForce")){ double val1, val2, val3; int edge; if(fscanf(f, "%d %lf %lf %lf", &edge, &val1, &val2, &val3) != 4){ fclose(f); return; } neumannBC neu; neu.g = new groupOfElements (1, edge); neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3)); neu._tag=edge; neu.onWhat=BoundaryCondition::ON_EDGE; allNeumann.push_back(neu); } else if (!strcmp(what, "FaceForce")){ double val1, val2, val3; int face; if(fscanf(f, "%d %lf %lf %lf", &face, &val1, &val2, &val3) != 4){ fclose(f); return; } neumannBC neu; neu.g = new groupOfElements (2, face); neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3)); neu._tag=face; neu.onWhat=BoundaryCondition::ON_FACE; allNeumann.push_back(neu); } else if (!strcmp(what, "VolumeForce")){ double val1, val2, val3; int volume; if(fscanf(f, "%d %lf %lf %lf", &volume, &val1, &val2, &val3) != 4){ fclose(f); return; } neumannBC neu; neu.g = new groupOfElements (3, volume); neu._f= new simpleFunction<SVector3>(SVector3(val1, val2, val3)); neu._tag=volume; neu.onWhat=BoundaryCondition::ON_VOLUME; allNeumann.push_back(neu); } else if (!strcmp(what, "MeshFile")){ char name[245]; if(fscanf(f, "%s", name) != 1){ fclose(f); return; } setMesh(name); } else if (!strcmp(what, "CutMeshPlane")){ double a, b, c, d; if(fscanf(f, "%lf %lf %lf %lf", &a, &b, &c, &d) != 4){ fclose(f); return; } int tag=1; gLevelsetPlane ls(a,b,c,d,tag); pModel = pModel->buildCutGModel(&ls); } else if (!strcmp(what, "CutMeshSphere")){ double x, y, z, r; if(fscanf(f, "%lf %lf %lf %lf", &x, &y, &z, &r) != 4){ fclose(f); return; } int tag=1; gLevelsetSphere ls(x,y,z,r,tag); pModel = pModel->buildCutGModel(&ls); } else { Msg::Error("Invalid input : '%s'", what); } } fclose(f); }
void updateBoVec<3, MFace>( const int normalSource, const MVertex *const vertex, const int zoneIndex, const int vertIndex, const CCon::FaceVector<MZoneBoundary<3>::GlobalVertexData<MFace>::FaceDataB> &faces, ZoneBoVec &zoneBoVec, BCPatchIndex &patch, bool &warnNormFromElem) { GEntity *ent; if(normalSource == NormalSourceElement) goto getNormalFromElements; ent = vertex->onWhat(); if(ent == 0) { goto getNormalFromElements; // No entity: try to find a normal from the faces } else { switch(ent->dim()) { case 0: case 1: /*--------------------------------------------------------------------* * In this case, there are possibly multiple GFaces from this zone * connected to the vertex. One patch for each GFace will be written. *--------------------------------------------------------------------*/ { //--Get a list of face entities connected to 'ent' std::list<GFace *> gFaceList; switch(ent->dim()) { case 0: { std::vector<GEdge *> gEdgeList = ent->edges(); std::list<GFace *> gFaceList; for(std::vector<GEdge *>::const_iterator gEIt = gEdgeList.begin(); gEIt != gEdgeList.end(); ++gEIt) { std::vector<GFace *> alist = (*gEIt)->faces(); gFaceList.insert(gFaceList.end(), alist.begin(), alist.end()); } // Remove duplicates gFaceList.sort(); gFaceList.unique(); } break; case 1: { std::vector<GFace *> fac = ent->faces(); gFaceList.insert(gFaceList.end(), fac.begin(), fac.end()); } break; } //--Get a list of face entities connected to the 'vertex' that are also // in the //--zone std::list<const GFace *> useGFace; std::vector<GEdge *> gEdgeList; const int nFace = faces.size(); for(int iFace = 0; iFace != nFace; ++iFace) { if(zoneIndex == faces[iFace].zoneIndex) { bool matchedFace = false; MFace mFace = faces[iFace].parentElement->getFace(faces[iFace].parentFace); const int nVOnF = mFace.getNumVertices(); int vertexOnF = 0; // The index of 'vertex' in the face for(int iVOnF = 0; iVOnF != nVOnF; ++iVOnF) { const MVertex *const vertex2 = mFace.getVertex(iVOnF); if(vertex == vertex2) vertexOnF = iVOnF; else { const GEntity *const ent2 = vertex2->onWhat(); if(ent2->dim() == 2) { matchedFace = true; useGFace.push_back(static_cast<const GFace *>(ent2)); break; } } } // Triangle MElements are a total P.I.T.A.: // - If the original 'ent' is a vertex, one MVertex can be on the // GVertex, and the other two on GEdges, and then the MElement is // still on the GFace. // - If the original 'ent' is an edge, one MVertex can be on the // original GEdge, another on a GVertex, and the final on another // GEdge, and then the MElement is still on the GFace. There is // also the unlikely case where the two other MVertex are both on // edges ... and the MElement is still on the GFace. if(!matchedFace && (3 == nVOnF)) { const MVertex *vertex2 = 0; const MVertex *vertex3 = 0; switch(vertexOnF) { case 0: vertex2 = mFace.getVertex(1); vertex3 = mFace.getVertex(2); break; case 1: vertex2 = mFace.getVertex(0); vertex3 = mFace.getVertex(2); break; case 2: vertex2 = mFace.getVertex(0); vertex3 = mFace.getVertex(1); break; } if(vertex2 && vertex3) { const GEntity *const ent2 = vertex2->onWhat(); const GEntity *const ent3 = vertex3->onWhat(); if(ent2 && ent3) { if(ent2->dim() == 1 && ent3->dim() == 1) { // Which GFace is bounded by edges ent2 and ent3? for(std::list<GFace *>::const_iterator gFIt = gFaceList.begin(); gFIt != gFaceList.end(); ++gFIt) { gEdgeList = (*gFIt)->edges(); if((std::find(gEdgeList.begin(), gEdgeList.end(), ent2) != gEdgeList.end()) && (std::find(gEdgeList.begin(), gEdgeList.end(), ent3) != gEdgeList.end())) { // Edges ent2 and ent3 bound this face useGFace.push_back(*gFIt); break; } } } else if(ent->dim() == 1 && (ent2->dim() + ent3->dim() == 1)) { const GEntity *entCmp; if(ent2->dim() == 1) entCmp = ent2; else entCmp = ent3; // Which GFace is bounded by entCmp for(std::list<GFace *>::const_iterator gFIt = gFaceList.begin(); gFIt != gFaceList.end(); ++gFIt) { gEdgeList = (*gFIt)->edges(); if(std::find(gEdgeList.begin(), gEdgeList.end(), entCmp) != gEdgeList.end()) { // Edge entCmp and the original edge bound this face useGFace.push_back(*gFIt); break; } } } } } } // Stupid triangles } // End if face in zone } // End loop over faces // Duplicates are a possibility, remove useGFace.sort(); useGFace.unique(); //--'useGFace' now contains the face entities that connect to vertex. A // BC //--patch will be written for each of them. for(std::list<const GFace *>::const_iterator gFIt = useGFace.begin(); gFIt != useGFace.end(); ++gFIt) { SPoint2 par; if(!reparamMeshVertexOnFace(const_cast<MVertex *>(vertex), *gFIt, par)) goto getNormalFromElements; // :P After all that! SVector3 boNormal = (*gFIt)->normal(par); SPoint3 interior(0., 0., 0.); int cFace = 0; const int nFace = faces.size(); for(int iFace = 0; iFace != nFace; ++iFace) { if(faces[iFace].zoneIndex == zoneIndex) { ++cFace; interior += faces[iFace].parentElement->barycenter(); } } interior /= cFace; if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.) boNormal.negate(); zoneBoVec.push_back( VertexBoundary(zoneIndex, (*gFIt)->tag(), boNormal, const_cast<MVertex *>(vertex), vertIndex)); patch.add((*gFIt)->tag()); } } break; case 2: /*--------------------------------------------------------------------* * The vertex exists on a face and belongs to only 1 BC patch. *--------------------------------------------------------------------*/ { const GFace *const gFace = static_cast<const GFace *>(ent); SPoint2 par; if(!reparamMeshVertexOnFace(const_cast<MVertex *>(vertex), gFace, par)) goto getNormalFromElements; SVector3 boNormal = static_cast<const GFace *>(ent)->normal(par); SPoint3 interior(0., 0., 0.); int cFace = 0; const int nFace = faces.size(); for(int iFace = 0; iFace != nFace; ++iFace) { if(faces[iFace].zoneIndex == zoneIndex) { ++cFace; interior += faces[iFace].parentElement->barycenter(); } } interior /= cFace; if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.) boNormal.negate(); zoneBoVec.push_back(VertexBoundary(zoneIndex, gFace->tag(), boNormal, const_cast<MVertex *>(vertex), vertIndex)); patch.add(gFace->tag()); } break; default: goto getNormalFromElements; } } return; getNormalFromElements:; /*--------------------------------------------------------------------* * Geometry information cannot be used - generate normals from the * elements *--------------------------------------------------------------------*/ { if(warnNormFromElem && normalSource == 1) { Msg::Warning("Some or all boundary normals were determined from mesh " "elements instead of from the geometry"); warnNormFromElem = false; } // Sum the normals from each element connected to the vertex and in the // zone. Each normal has to be converted independently into an inwards- // pointing normal. //**Weight each normal by the area of the boundary element? SVector3 boNormal(0.); const int nFace = faces.size(); for(int iFace = 0; iFace != nFace; ++iFace) { if(faces[iFace].zoneIndex == zoneIndex) { // Normal to the boundary (unknown direction) SVector3 bnt = faces[iFace].parentElement->getFace(faces[iFace].parentFace).normal(); // Inwards normal const SVector3 inwards(vertex->point(), faces[iFace].parentElement->barycenter()); if(dot(bnt, inwards) < 0.) bnt.negate(); boNormal += bnt; } } boNormal.normalize(); zoneBoVec.push_back(VertexBoundary( zoneIndex, 0, boNormal, const_cast<MVertex *>(vertex), vertIndex)); patch.add(0); } }
SVector3 gmshSurface::normal(const SPoint2 ¶m) const { Msg::Error("Normal computation not implemented for this type of surface"); return SVector3(); }
int GModel::readSTL(const std::string &name, double tolerance) { FILE *fp = Fopen(name.c_str(), "rb"); if(!fp){ Msg::Error("Unable to open file '%s'", name.c_str()); return 0; } // store triplets of points for each solid found in the file std::vector<std::vector<SPoint3> > points; SBoundingBox3d bbox; // "solid", or binary data header char buffer[256]; if(!fgets(buffer, sizeof(buffer), fp)){ fclose(fp); return 0; } bool binary = strncmp(buffer, "solid", 5) && strncmp(buffer, "SOLID", 5); // ASCII STL if(!binary){ points.resize(1); while(!feof(fp)) { // "facet normal x y z" or "endsolid" if(!fgets(buffer, sizeof(buffer), fp)) break; if(!strncmp(buffer, "endsolid", 8) || !strncmp(buffer, "ENDSOLID", 8)){ // "solid" if(!fgets(buffer, sizeof(buffer), fp)) break; if(!strncmp(buffer, "solid", 5) || !strncmp(buffer, "SOLID", 5)){ points.resize(points.size() + 1); // "facet normal x y z" if(!fgets(buffer, sizeof(buffer), fp)) break; } } // "outer loop" if(!fgets(buffer, sizeof(buffer), fp)) break; // "vertex x y z" for(int i = 0; i < 3; i++){ if(!fgets(buffer, sizeof(buffer), fp)) break; char s1[256]; double x, y, z; if(sscanf(buffer, "%s %lf %lf %lf", s1, &x, &y, &z) != 4) break; SPoint3 p(x, y, z); points.back().push_back(p); bbox += p; } // "endloop" if(!fgets(buffer, sizeof(buffer), fp)) break; // "endfacet" if(!fgets(buffer, sizeof(buffer), fp)) break; } } // check if we could parse something bool empty = true; for(unsigned int i = 0; i < points.size(); i++){ if(points[i].size()){ empty = false; break; } } if(empty) points.clear(); // binary STL (we also try to read in binary mode if the header told // us the format was ASCII but we could not read any vertices) if(binary || empty){ if(binary) Msg::Info("Mesh is in binary format"); else Msg::Info("Wrong ASCII header or empty file: trying binary read"); rewind(fp); while(!feof(fp)) { char header[80]; if(!fread(header, sizeof(char), 80, fp)) break; unsigned int nfacets = 0; size_t ret = fread(&nfacets, sizeof(unsigned int), 1, fp); bool swap = false; if(nfacets > 100000000){ Msg::Info("Swapping bytes from binary file"); swap = true; SwapBytes((char*)&nfacets, sizeof(unsigned int), 1); } if(ret && nfacets){ points.resize(points.size() + 1); char *data = new char[nfacets * 50 * sizeof(char)]; ret = fread(data, sizeof(char), nfacets * 50, fp); if(ret == nfacets * 50){ for(unsigned int i = 0; i < nfacets; i++) { float *xyz = (float *)&data[i * 50 * sizeof(char)]; if(swap) SwapBytes((char*)xyz, sizeof(float), 12); for(int j = 0; j < 3; j++){ SPoint3 p(xyz[3 + 3 * j], xyz[3 + 3 * j + 1], xyz[3 + 3 * j + 2]); points.back().push_back(p); bbox += p; } } } delete [] data; } } } std::vector<GFace*> faces; for(unsigned int i = 0; i < points.size(); i++){ if(points[i].empty()){ Msg::Error("No facets found in STL file for solid %d", i); fclose(fp); return 0; } if(points[i].size() % 3){ Msg::Error("Wrong number of points (%d) in STL file for solid %d", points[i].size(), i); fclose(fp); return 0; } Msg::Info("%d facets in solid %d", points[i].size() / 3, i); // create face GFace *face = new discreteFace(this, getMaxElementaryNumber(2) + 1); faces.push_back(face); add(face); } // create triangles using unique vertices double eps = norm(SVector3(bbox.max(), bbox.min())) * tolerance; std::vector<MVertex*> vertices; for(unsigned int i = 0; i < points.size(); i++) for(unsigned int j = 0; j < points[i].size(); j++) vertices.push_back(new MVertex(points[i][j].x(), points[i][j].y(), points[i][j].z())); MVertexPositionSet pos(vertices); std::set<MFace,Less_Face> unique; int nbDuplic = 0; for(unsigned int i = 0; i < points.size(); i ++){ for(unsigned int j = 0; j < points[i].size(); j += 3){ MVertex *v[3]; for(int k = 0; k < 3; k++){ double x = points[i][j + k].x(); double y = points[i][j + k].y(); double z = points[i][j + k].z(); v[k] = pos.find(x, y, z, eps); } MFace mf (v[0], v[1], v[2]); if (unique.find(mf) == unique.end()){ faces[i]->triangles.push_back(new MTriangle(v[0], v[1], v[2])); unique.insert(mf); } else{ nbDuplic++; } } } if (nbDuplic) Msg::Warning("%d duplicate triangles in STL file", nbDuplic); _associateEntityWithMeshVertices(); _storeVerticesInEntities(vertices); // will delete unused vertices fclose(fp); return 1; }
PView *GMSH_DistancePlugin::execute(PView *v) { int id_pt = (int) DistanceOptions_Number[0].def; int id_line = (int) DistanceOptions_Number[1].def; int id_face = (int) DistanceOptions_Number[2].def; double type = (double) DistanceOptions_Number[3].def; int ortho = (int) DistanceOptions_Number[6].def; PView *view = new PView(); _data = getDataList(view); #if defined(HAVE_SOLVER) #if defined(HAVE_TAUCS) linearSystemCSRTaucs<double> *lsys = new linearSystemCSRTaucs<double>; #else linearSystemCSRGmm<double> *lsys = new linearSystemCSRGmm<double>; lsys->setNoisy(1); lsys->setGmres(1); lsys->setPrec(5.e-8); #endif dofManager<double> * dofView = new dofManager<double>(lsys); #endif std::vector<GEntity*> _entities; GModel::current()->getEntities(_entities); if (!_entities.size() || !_entities[_entities.size()-1]->getMeshElement(0)) { Msg::Error("This plugin needs a mesh !"); return view; } GEntity* ge = _entities[_entities.size()-1]; int integrationPointTetra[2] = {0,0}; int numnodes = 0; for (unsigned int i = 0; i < _entities.size()-1; i++) numnodes += _entities[i]->mesh_vertices.size(); int totNodes = numnodes + _entities[_entities.size()-1]->mesh_vertices.size(); int order = ge->getMeshElement(0)->getPolynomialOrder(); int totNumNodes = totNodes + ge->getNumMeshElements()*integrationPointTetra[order-1]; std::vector<SPoint3> pts; std::vector<double> distances; std::vector<MVertex* > pt2Vertex; pts.clear(); distances.clear(); pt2Vertex.clear(); pts.reserve(totNumNodes); distances.reserve(totNumNodes); pt2Vertex.reserve(totNumNodes); std::map<MVertex*,double> _distanceE_map; std::map<MVertex*,int> _isInYarn_map; std::vector<int> index; std::vector<double> distancesE; std::vector<double> distances2; std::vector<double> distancesE2; std::vector<int> isInYarn; std::vector<int> isInYarn2; std::vector<SPoint3> closePts; std::vector<SPoint3> closePts2; for (int i=0; i<totNumNodes; i++) { distances.push_back(1.e22); } int k = 0; for (unsigned int i=0; i<_entities.size(); i++){ GEntity* ge = _entities[i]; _maxDim = std::max(_maxDim, ge->dim()); for (unsigned int j=0; j<ge->mesh_vertices.size(); j++) { MVertex *v = ge->mesh_vertices[j]; pts.push_back(SPoint3(v->x(), v->y(), v->z())); _distance_map.insert(std::make_pair(v, 0.0)); /* TO DO (by AM) SPoint3 p_empty(); _closePts_map.insert(std::make_pair(v, p_empty)); */ pt2Vertex[k] = v; k++; } } // Compute geometrical distance to mesh boundaries //------------------------------------------------------ if (type < 0.0 ) { bool existEntity = false; for (unsigned int i=0; i<_entities.size(); i++) { GEntity* g2 = _entities[i]; int gDim = g2->dim(); std::vector<int> phys = g2->getPhysicalEntities(); bool computeForEntity = false; for(unsigned int k = 0; k<phys.size(); k++) { int tagp = phys[k]; if (id_pt == 0 && id_line == 0 && id_face == 0 && gDim == _maxDim - 1) computeForEntity = true; else if ((tagp == id_pt && gDim == 0) || (tagp == id_line && gDim == 1) || (tagp == id_face && gDim == 2)) computeForEntity = true; } if (computeForEntity) { existEntity = true; for (unsigned int k = 0; k < g2->getNumMeshElements(); k++) { std::vector<double> iDistances; std::vector<SPoint3> iClosePts; std::vector<double> iDistancesE; std::vector<int> iIsInYarn; MElement *e = g2->getMeshElement(k); MVertex *v1 = e->getVertex(0); MVertex *v2 = e->getVertex(1); SPoint3 p1(v1->x(), v1->y(), v1->z()); SPoint3 p2(v2->x(), v2->y(), v2->z()); if ((e->getNumVertices() == 2 && order == 1) || (e->getNumVertices() == 3 && order == 2)) { signedDistancesPointsLine(iDistances, iClosePts, pts, p1, p2); } else if ((e->getNumVertices() == 3 && order == 1) || (e->getNumVertices() == 6 && order == 2)) { MVertex *v3 = e->getVertex(2); SPoint3 p3 (v3->x(),v3->y(),v3->z()); signedDistancesPointsTriangle(iDistances, iClosePts, pts, p1, p2, p3); } for (unsigned int kk=0; kk<pts.size(); kk++) { if (std::abs(iDistances[kk]) < distances[kk]) { distances[kk] = std::abs(iDistances[kk]); MVertex *v = pt2Vertex[kk]; _distance_map[v] = distances[kk]; /* TO DO (by AM) _closePts_map[v] = iClosePts[kk]; */ } } } } } if (!existEntity){ if (id_pt != 0) Msg::Error("The Physical Point does not exist !"); if (id_line != 0) Msg::Error("The Physical Line does not exist !"); if (id_face != 0) Msg::Error("The Physical Surface does not exist !"); return view; } printView(_entities, _distance_map); /* TO DO (by AM) printView(_entities, _closePts_map); */ } // Compute PDE for distance function //----------------------------------- else if (type > 0.0) { #if defined(HAVE_SOLVER) bool existEntity = false; SBoundingBox3d bbox; for(unsigned int i = 0; i < _entities.size(); i++){ GEntity* ge = _entities[i]; int gDim = ge->dim(); bool fixForEntity = false; std::vector<int> phys = ge->getPhysicalEntities(); for(unsigned int k = 0; k < phys.size(); k++) { int tagp = phys[k]; if (id_pt == 0 && id_line == 0 && id_face == 0 && gDim == _maxDim - 1) fixForEntity = true; else if ((tagp == id_pt && gDim == 0) || (tagp == id_line && gDim == 1) || (tagp == id_face && gDim == 2) ) fixForEntity = true; } if (fixForEntity) { existEntity = true; for (unsigned int i = 0; i < ge->getNumMeshElements(); ++i) { MElement *t = ge->getMeshElement(i); for (int k=0; k<t->getNumVertices(); k++) { MVertex *v = t->getVertex(k); dofView->fixVertex(v, 0, 1, 0.); bbox += SPoint3(v->x(), v->y(), v->z()); } } } } if (!existEntity){ if (id_pt != 0) Msg::Error("The Physical Point does not exist !"); if (id_line != 0) Msg::Error("The Physical Line does not exist !"); if (id_face != 0) Msg::Error("The Physical Surface does not exist !"); return view; } std::vector<MElement *> allElems; for(unsigned int ii = 0; ii < _entities.size(); ii++){ if(_entities[ii]->dim() == _maxDim) { GEntity *ge = _entities[ii]; for(unsigned int i = 0; i < ge->getNumMeshElements(); ++i) { MElement *t = ge->getMeshElement(i); allElems.push_back(t); for (int k = 0; k < t->getNumVertices(); k++) dofView->numberVertex(t->getVertex(k), 0, 1); } } } double L = norm(SVector3(bbox.max(), bbox.min())); double mu = type*L; simpleFunction<double> DIFF(mu*mu), ONE(1.0); distanceTerm distance(GModel::current(), 1, &DIFF, &ONE); for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ SElement se((*it)); distance.addToMatrix(*dofView, &se); } groupOfElements gr(allElems); distance.addToRightHandSide(*dofView, gr); Msg::Info("Distance Computation: Assembly done"); lsys->systemSolve(); Msg::Info("Distance Computation: System solved"); for (std::map<MVertex*,double >::iterator itv = _distance_map.begin(); itv != _distance_map.end() ; ++itv) { MVertex *v = itv->first; double value; dofView->getDofValue(v, 0, 1, value); value = std::min(0.9999, value); double dist = -mu * log(1. - value); itv->second = dist; } printView(_entities, _distance_map); #endif } _data->setName("distance"); _data->Time.push_back(0); _data->setFileName(_fileName.c_str()); _data->finalize(); // compute also orthogonal vector to distance field // A Uortho = -C DIST //------------------------------------------------ if (ortho > 0) { #if defined(HAVE_SOLVER) #ifdef HAVE_TAUCS linearSystemCSRTaucs<double> *lsys2 = new linearSystemCSRTaucs<double>; #else linearSystemCSRGmm<double> *lsys2 = new linearSystemCSRGmm<double>; lsys->setNoisy(1); lsys->setGmres(1); lsys->setPrec(5.e-8); #endif dofManager<double> myAssembler(lsys2); simpleFunction<double> ONE(1.0); double dMax = 1.0; //EMI TO CHANGE std::vector<MElement *> allElems; for(unsigned int ii = 0; ii < _entities.size(); ii++){ if (_entities[ii]->dim() == _maxDim) { GEntity *ge = _entities[ii]; for (unsigned int i=0; i<ge->getNumMeshElements(); ++i) { MElement *t = ge->getMeshElement(i); double vMean = 0.0; for (int k = 0; k < t->getNumVertices(); k++) { std::map<MVertex*, double>::iterator it = _distance_map.find(t->getVertex(k)); vMean += it->second; } vMean /= t->getNumVertices(); if (vMean < dMax) allElems.push_back(ge->getMeshElement(i)); } } } int mid = (int)floor(allElems.size() / 2.); MElement *e = allElems[mid]; MVertex *vFIX = e->getVertex(0); myAssembler.fixVertex(vFIX, 0, 1, 0.0); for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ MElement *t = *it; for(int k = 0; k < t->getNumVertices(); k++) myAssembler.numberVertex(t->getVertex(k), 0, 1); } orthogonalTerm *ortho; ortho = new orthogonalTerm(GModel::current(), 1, &ONE, &_distance_map); // if (type < 0) // ortho = new orthogonalTerm(GModel::current(), 1, &ONE, view); // else // ortho = new orthogonalTerm(GModel::current(), 1, &ONE, dofView); for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ SElement se((*it)); ortho->addToMatrix(myAssembler, &se); } groupOfElements gr(allElems); ortho->addToRightHandSide(myAssembler, gr); Msg::Info("Orthogonal Computation: Assembly done"); lsys2->systemSolve(); Msg::Info("Orthogonal Computation: System solved"); PView *view2 = new PView(); PViewDataList *data2 = getDataList(view2); data2->setName("ortogonal field"); Msg::Info("Writing orthogonal.pos"); FILE * f5 = Fopen("orthogonal.pos","w"); fprintf(f5,"View \"orthogonal\"{\n"); for (std::vector<MElement* >::iterator it = allElems.begin(); it != allElems.end(); it++){ MElement *e = *it; int numNodes = e->getNumVertices(); if (e->getType() == TYPE_POLYG) numNodes = e->getNumChildren() * e->getChild(0)->getNumVertices(); std::vector<double> x(numNodes), y(numNodes), z(numNodes); std::vector<double> *out2 = data2->incrementList(1, e->getType(), numNodes); std::vector<MVertex*> nods; std::vector<double> orth; if(!e->getNumChildren()) for(int i=0; i<numNodes; i++) nods.push_back(e->getVertex(i)); else for(int i = 0; i < e->getNumChildren(); i++) for(int j = 0; j < e->getChild(i)->getNumVertices(); j++) nods.push_back(e->getChild(i)->getVertex(j)); for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->x()); for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->y()); for(int nod = 0; nod < numNodes; nod++) out2->push_back((nods[nod])->z()); if (_maxDim == 2) switch (numNodes) { case 2: fprintf(f5,"SL("); break; case 3: fprintf(f5,"ST("); break; case 4: fprintf(f5,"SQ("); break; default: Msg::Fatal("Error in Plugin 'Distance' (numNodes=%g).",numNodes); break; } else if (_maxDim == 3) switch (numNodes) { case 4: fprintf(f5,"SS("); break; case 8: fprintf(f5,"SH("); break; case 6: fprintf(f5,"SI("); break; case 5: fprintf(f5,"SY("); break; default: Msg::Fatal("Error in Plugin 'Distance' (numNodes=%g).",numNodes); break; } for (int j=0; j<numNodes; j++) { MVertex *v = nods[j]; if (j) fprintf(f5, ",%g,%g,%g", v->x(), v->y(), v->z()); else fprintf(f5, "%g,%g,%g", v->x(), v->y(), v->z()); double value; myAssembler.getDofValue(v, 0, 1, value); orth.push_back(value); } fprintf(f5,"){"); for (unsigned int i=0; i<orth.size(); i++) { out2->push_back(orth[i]); if (i) fprintf(f5,",%g", orth[i]); else fprintf(f5,"%g", orth[i]); } fprintf(f5,"};\n"); } fprintf(f5,"};\n"); fclose(f5); lsys->clear(); lsys2->clear(); data2->Time.push_back(0); data2->setFileName("orthogonal.pos"); data2->finalize(); #endif } return view; }