double geometryUtils::computeVoronoiArea(Vertex_handle vertex) { double voronoiArea = 0.0; Vertex_circulator j; j = vertex->vertex_begin(); do { Point_3 p11 = j->vertex()->point(); Point_3 p12 = j->next()->vertex()->point(); Point_3 p13 = j->next()->next()->vertex()->point(); Vector_3 v11 = p13 - p12; Vector_3 v12 = p11 - p12; v11 = v11 / sqrt(CGAL::to_double(v11.squared_length())); v12 = v12 / sqrt(CGAL::to_double(v12.squared_length())); double alpha = acos(CGAL::to_double(v11 * v12)); Point_3 p22 = j->opposite()->vertex()->point(); Point_3 p23 = j->opposite()->next()->vertex()->point(); Vector_3 v21 = p11 - p23; Vector_3 v22 = p22 - p23; v21 = v21 / sqrt(CGAL::to_double(v21.squared_length())); v22 = v22 / sqrt(CGAL::to_double(v22.squared_length())); double beta = acos(CGAL::to_double(v21 * v22)); Vector_3 x = p13 - p11; double length = CGAL::to_double(x.squared_length()); voronoiArea += (1.0 / 8.0) * (1.0 / tan(alpha) + 1.0 / tan(beta)) * length; } while (++j != vertex->vertex_begin()); return voronoiArea; };
void rotate_points3d(const Eigen::MatrixXd& ptsin, const Point_3& center, const Vector_3& direction, double angle, Eigen::MatrixXd& ptsout) { Eigen::Vector3d c(center.x(), center.y(), center.z()); Eigen::Vector3d dir(direction.x(), direction.y(), direction.z()); Eigen::Matrix4d rotMat = create_rotation3d_line_angle(center, direction, angle); ptsout.resize(ptsin.rows(), ptsin.cols() ); ptsout = transform_point3d(ptsin, rotMat); }
void add_neighbourhood_to_hullPoints(pointVector& hullPoints, const Vertex_const_handle& vert, const double& tapeSize) { Point_3 pnt = vert->point(); hullPoints.push_back(pnt); // Add vertex point Nef_polyhedron::SVertex_const_iterator svcIt = vert->svertices_begin(), svcItEND = vert->svertices_end(); CGAL_For_all(svcIt,svcItEND) { Vector_3 vecR(pnt,svcIt->target()->point()); Vector_3 vecRnew = vecR * tapeSize / std::sqrt(CGAL::to_double(vecR.squared_length())); if ((vecR.squared_length()-OVERLAP_DIST_THRESHOLD) > vecRnew.squared_length()) hullPoints.push_back(pnt+vecRnew); // Add svertex neighbourhood point (tapesize away from vertex) else hullPoints.push_back(svcIt->target()->point()); }
//compute the cross point Point_3 compute_cross_point(Plane_3 plane, Point_3 start, Point_3 end) { Vector_3 normal = plane.orthogonal_vector(); Vector_3 line_direction = end - start; Point_3 p= plane.point(); double t; double a = (start.x() - p.x()) * normal.x() + (start.y() - p.y()) * normal.y() + (start.z() - p.z()) * normal.z(); double b = line_direction.x() * normal.x() + line_direction.y() * normal.y() + line_direction.z() * normal.z(); assert(b != 0); t = -a / b; return start + t * line_direction; }
/** * True if u is steeper than v. Uses the square of slope to avoid sqrt. */ bool is_steeper(Vector_3 u, Vector_3 v) { Vector_2 u_2 = Vector_2(u.x(), u.y()); Vector_2 v_2 = Vector_2(v.x(), v.y()); return ((u.z() * u.z() / u_2.squared_length()) > (v.z() * v.z() / v_2.squared_length())); }
// Assign either ceiling, floor or the default semantic based on input booleans and normal vector void assignCeilVloor(std::set<Polyhedron::Facet_handle>& fhSet, bool canBeUp, bool canBeDown) { pointVector facetPoints; Vector_3 ortVec; for (std::set<Polyhedron::Facet_handle>::iterator sfIt=fhSet.begin();sfIt!=fhSet.end();++sfIt) { if (!canBeUp && !canBeDown) { (*sfIt)->semanticBLA = DEFAULT_HOR_SEMANTIC; continue; } facetPoints = comp_facetPoints(*sfIt); CGAL::normal_vector_newell_3(facetPoints.begin(),facetPoints.end(),ortVec); if (!normalizeVector(ortVec)) continue; if (canBeDown && ortVec.z() <= -HORIZONTAL_ANGLE_RANGE ) (*sfIt)->semanticBLA = DEFAULT_DOWN_SEMANTIC; else if (canBeUp && ortVec.z() >= HORIZONTAL_ANGLE_RANGE ) (*sfIt)->semanticBLA = DEFAULT_UP_SEMANTIC; else (*sfIt)->semanticBLA = DEFAULT_HOR_SEMANTIC; } }
int PlasmaBunch::interaction(int m, int sum){ register int i, j,k; static Vector_3 r; int ret=Plasma::interaction(m,sum); // now interacting with bunch particles int type=0; // ion-ion double dEcoul,dEpotent,dQuant; double df; for(i=0;i<(m<0 ? n : m+1);i++){ if(i>=ni)type|=0x1;// setting electron-? interaction type else type&=0x2;// setting ion-? interaction type if(is_ion)type&=0x1; // setting ?-ion interaction type else type|=0x2;// setting ?-electron interaction type for(j=0;j<nb;j++){ for(k=0;k<3;k++){ // determining the closest //distance and correspondent direction r[k]=xx[i][k]-xb[j][k]; if(r[k]>L/2)r[k]-=L; if(r[k]<-L/2)r[k]+=L; } double R=r.norm(); if(R<1e-20)printf("Got small distance to bunch (%d,b%d) !\n",i,j); r/=R; dEcoul=qb/R; df=potential(type,R,dEpotent,dQuant); for(k=0;k<3;k++){ // to avoid vector copying f[i][k]+=df*r[k]; //f[j][k]-=df*r[k]; } Ecoul+=dEcoul; Quant+=dQuant; Epotent+=dEpotent; } } return ret; }
void Viewer::alphaChanged() { normals.resize(0); pos_poly.resize(0); std::list<Facet> facets; scene->alpha_shape.get_alpha_shape_facets(std::back_inserter(facets), Alpha_shape_3::REGULAR); for(std::list<Facet>::iterator fit = facets.begin(); fit != facets.end(); ++fit) { const Cell_handle& ch = fit->first; const int index = fit->second; //const Vector_3& n = ch->normal(index); // must be unit vector const Point_3& a = ch->vertex((index+1)&3)->point(); const Point_3& b = ch->vertex((index+2)&3)->point(); const Point_3& c = ch->vertex((index+3)&3)->point(); Vector_3 v = CGAL::unit_normal(a,b,c); normals.push_back(v.x()); normals.push_back(v.y()); normals.push_back(v.z()); normals.push_back(v.x()); normals.push_back(v.y()); normals.push_back(v.z()); normals.push_back(v.x()); normals.push_back(v.y()); normals.push_back(v.z()); pos_poly.push_back(a.x()); pos_poly.push_back(a.y()); pos_poly.push_back(a.z()); pos_poly.push_back(b.x()); pos_poly.push_back(b.y()); pos_poly.push_back(b.z()); pos_poly.push_back(c.x()); pos_poly.push_back(c.y()); pos_poly.push_back(c.z()); } initialize_buffers(); }
static std::vector<Point_3> mapPointsFromOXYplane(std::vector<Point_2> points, Vector_3 nu) { DEBUG_START; ASSERT(!!Vector3d(nu.x(), nu.y(), nu.z()) && "nu is null vector"); Vector_3 ez(0., 0, 1.); double length = sqrt(nu.squared_length()); ASSERT(std::fpclassify(length) != FP_ZERO); nu = nu * 1. / length; /* Normalize std::vector \nu. */ ASSERT(std::isfinite(nu.x())); ASSERT(std::isfinite(nu.y())); ASSERT(std::isfinite(nu.z())); Vector_3 tau = cross_product(nu, ez); std::vector<Point_3> pointsMapped; CGAL::Origin o; for (auto &point : points) { pointsMapped.push_back(o + tau * point.x() + ez * point.y()); } DEBUG_END; return pointsMapped; }
// Réalise un impact sur la face fs à partir d'une liste de points à déplacer, répartis par couronne (pts[0] = première couronne intérieure, pts[0][0] = premier point de la première couronne) void DegradeAnObject::impactTheFacetArea(std::vector< std::vector<Point_3> > pts, Facet fs, double ray, int index) { double str = 0.02; Vector_3 normal = normalizeVector(getNormalOfFacet(fs)); Kernel::Plane_3 pl(fs.halfedge()->vertex()->point(), normal); for(int i = 0 ; i < pts.size() ; i++) { for(int j = 0 ; j < pts[i].size() ; j++) { bool chk = false; Point_iterator pi = polys[index].points_begin(); while(!chk) { ++pi; if(*pi == pts[i][j]) { *pi = Point_3(pi->x() - (impactStrengh(str, i))*normal.x(), pi->y() - (impactStrengh(str, i))*normal.y(), pi->z() - (impactStrengh(str, i))*normal.z()); chk = true; } } } } }
static Vector_3 leastSquaresPoint(const std::vector<unsigned> activeGroup, const std::vector<SupportItem> &items) { DEBUG_START; Eigen::Matrix3d matrix; Eigen::Vector3d vector; for (unsigned i = 0; i < 3; ++i) { vector(i) = 0.; for (unsigned j = 0; j < 3; ++j) matrix(i, j) = 0.; } std::cout << "Calculating least squares points for the following items" << std::endl; for (unsigned iPlane : activeGroup) { SupportItem item = items[iPlane]; Vector_3 u = item.direction; double value = item.value; std::cout << " Item #" << iPlane << ": u = " << u << "; h = " << value << std::endl; for (unsigned i = 0; i < 3; ++i) { for (unsigned j = 0; j < 3; ++j) matrix(i, j) += u.cartesian(i) * u.cartesian(j); vector(i) += u.cartesian(i) * value; } } Eigen::Vector3d solution = matrix.inverse() * vector; Vector_3 result(solution(0), solution(1), solution(2)); std::cout << "Result: " << result << std::endl; for (unsigned iPlane : activeGroup) { SupportItem item = items[iPlane]; double delta = item.direction * result - item.value; std::cout << " delta = " << delta << std::endl; } DEBUG_END; return result; }
void buildFacets(Polyhedron_3 polyhedron, std::vector<SimpleEdge_3> &edges, std::vector<Vector_3> &U, std::vector<double> &H, std::map<int, int> &indices) { DEBUG_START; std::vector<Plane_3> planes = renumerateFacets(polyhedron, edges, indices); for (const Plane_3 &plane : planes) { Vector_3 norm = plane.orthogonal_vector(); double length = sqrt(norm.squared_length()); norm = norm * (1. / length); double value = -plane.d() / length; ASSERT(value > 0.); U.push_back(norm); H.push_back(value); } DEBUG_END; }
// Computes the intersection C+uV of the planes M*x+D=0 and N*x+E=0. // Returns -1 if there are no intersections (parallel), 0 for a line // intersection and 1 for co-planarity. // precondition: A, B are normalized (hessian form) int plane_plane_intersection(const Vector_3& M, const double D, const Vector_3& N, const double E, Point_3& C, Vector_3& V) { typedef CGAL::Cartesian<double> K; typedef CGAL::Plane_3<K> Plane_3; typedef CGAL::Line_3<K> Line_3; Plane_3 P1(M.x(), M.y(), M.z(), D); Plane_3 P2(N.x(), N.y(), N.z(), E); CGAL::Object result = CGAL::intersection(P1, P2); if (const Line_3 *iline = CGAL::object_cast<Line_3>(&result)) { CGAL::Point_3<K> p = iline->point(0); CGAL::Vector_3<K> v = iline->to_vector(); C = Point_3(p.x(), p.y(), p.z()); V = Vector_3(v.x(), v.y(), v.z()); return 0; } else if (const Plane_3 *iplane = CGAL::object_cast<Plane_3>(&result)) { return 1; } else { return -1; } }
int line_plane_intersection(const Point_3& B, const Vector_3& M, const Vector_3& N, const double D, Point_3& p) { typedef CGAL::Cartesian<double> K; typedef CGAL::Plane_3<K> Plane_3; typedef CGAL::Line_3<K> Line_3; CGAL::Point_3<K> CB(B.x(), B.y(), B.z()); CGAL::Vector_3<K> CM(M.x(), M.y(), M.z()); Line_3 L(CB, CM); Plane_3 P(N.x(), N.y(), N.z(), D); CGAL::Object result = CGAL::intersection(L, P); if (const CGAL::Point_3<K> *ipoint = CGAL::object_cast<CGAL::Point_3<K> >(&result)) { p = Point_3(ipoint->x(), ipoint->y(), ipoint->z()); return 0; } else if (const Line_3 *iline = CGAL::object_cast<Line_3>(&result)) { return 1; } else { return -1; } }
Polyhedron_3 obtainPolyhedron(Polyhedron_3 initialP, std::map<int, int> map, IpoptTopologicalCorrector *FTNLP) { DEBUG_START; std::vector<Vector_3> directions = FTNLP->getDirections(); std::vector<double> values = FTNLP->getValues(); std::vector<Plane_3> planes(initialP.size_of_facets()); unsigned iFacet = 0; for (auto I = initialP.facets_begin(), E = initialP.facets_end(); I != E; ++I) { auto it = map.find(iFacet); if (it != map.end()) { int i = it->second; Vector_3 u = directions[i]; double h = values[i]; ASSERT(h > 0); planes[iFacet] = Plane_3(-u.x(), -u.y(), -u.z(), h); std::cout << "Changing plane #" << iFacet << ": " << I->plane() << " |--> " << planes[iFacet] << std::endl; } else { planes[iFacet] = I->plane(); } ++iFacet; } Polyhedron_3 intersection(planes); std::cout << "Change in facets number: " << initialP.size_of_facets() << " -> " << intersection.size_of_facets() << std::endl; ASSERT(initialP.size_of_facets() - intersection.size_of_facets() < map.size() && "It seems that all extracted facets have gone"); DEBUG_END; return intersection; }
void buildMainTopology(std::vector<SimpleEdge_3> &edges, std::vector<Vector_3> &u, std::vector<double> &h, std::vector<Vector_3> &points, FixedTopology *FT) { DEBUG_START; unsigned iTangient = 0; for (unsigned i = 0; i < edges.size(); ++i) { Vector_3 A = edges[i].A; Vector_3 B = edges[i].B; for (const Plane_3 plane : edges[i].tangients) { Vector_3 norm = plane.orthogonal_vector(); double length = sqrt(norm.squared_length()); norm = norm * (1. / length); double value = -plane.d() / length; ASSERT(value > 0.); u.push_back(norm); h.push_back(value); if (norm * A > norm * B) FT->tangient[2 * i].insert(iTangient); else FT->tangient[2 * i + 1].insert(iTangient); ++iTangient; } FT->incident[edges[i].iForward].insert(2 * i); FT->incident[edges[i].iForward].insert(2 * i + 1); FT->incident[edges[i].iBackward].insert(2 * i); FT->incident[edges[i].iBackward].insert(2 * i + 1); points.push_back(A); points.push_back(B); } ASSERT(iTangient > 0); DEBUG_END; }
Point_3 vec_to_point(const Vector_3& v) { return Point_3(v.x(),v.y(),v.z()); }
IGL_INLINE bool igl::copyleft::cgal::segment_segment_squared_distance( const CGAL::Segment_3<Kernel> & S1, const CGAL::Segment_3<Kernel> & S2, CGAL::Point_3<Kernel> & P1, CGAL::Point_3<Kernel> & P2, typename Kernel::FT & dst) { typedef CGAL::Point_3<Kernel> Point_3; typedef CGAL::Vector_3<Kernel> Vector_3; typedef typename Kernel::FT EScalar; if(S1.is_degenerate()) { // All points on S1 are the same P1 = S1.source(); point_segment_squared_distance(P1,S2,P2,dst); return true; }else if(S2.is_degenerate()) { assert(!S1.is_degenerate()); // All points on S2 are the same P2 = S2.source(); point_segment_squared_distance(P2,S1,P1,dst); return true; } assert(!S1.is_degenerate()); assert(!S2.is_degenerate()); Vector_3 u = S1.target() - S1.source(); Vector_3 v = S2.target() - S2.source(); Vector_3 w = S1.source() - S2.source(); const auto a = u.dot(u); // always >= 0 const auto b = u.dot(v); const auto c = v.dot(v); // always >= 0 const auto d = u.dot(w); const auto e = v.dot(w); const auto D = a*c - b*b; // always >= 0 assert(D>=0); const auto sc=D, sN=D, sD = D; // sc = sN / sD, default sD = D >= 0 const auto tc=D, tN=D, tD = D; // tc = tN / tD, default tD = D >= 0 bool parallel = false; // compute the line parameters of the two closest points if (D==0) { // the lines are almost parallel parallel = true; sN = 0.0; // force using source point on segment S1 sD = 1.0; // to prevent possible division by 0.0 later tN = e; tD = c; } else { // get the closest points on the infinite lines sN = (b*e - c*d); tN = (a*e - b*d); if (sN < 0.0) { // sc < 0 => the s=0 edge is visible sN = 0.0; tN = e; tD = c; } else if (sN > sD) { // sc > 1 => the s=1 edge is visible sN = sD; tN = e + b; tD = c; } } if (tN < 0.0) { // tc < 0 => the t=0 edge is visible tN = 0.0; // recompute sc for this edge if (-d < 0.0) { sN = 0.0; }else if (-d > a) { sN = sD; }else { sN = -d; sD = a; } }else if (tN > tD) { // tc > 1 => the t=1 edge is visible tN = tD; // recompute sc for this edge if ((-d + b) < 0.0) { sN = 0; }else if ((-d + b) > a) { sN = sD; }else { sN = (-d + b); sD = a; } } // finally do the division to get sc and tc sc = (abs(sN) == 0 ? 0.0 : sN / sD); tc = (abs(tN) == 0 ? 0.0 : tN / tD); // get the difference of the two closest points P1 = S1.source() + sc*(S1.target()-S1.source()); P2 = S2.source() + sc*(S2.target()-S2.source()); Vector_3 dP = w + (sc * u) - (tc * v); // = S1(sc) - S2(tc) assert(dP == (P1-P2)); dst = dP.squared_length(); // return the closest distance return parallel; }
void Viewer::drawEdge(const Point_3& from, const Point_3& to, const QColor& clr, float r) { /* Draw regular lines */ if( m_isFlat ) { // disable lighting ::glDisable( GL_LIGHTING ); ::glLineWidth(1.0); qglColor( clr ); ::glBegin(GL_LINES); ::glVertex3f( from.x(), from.y(), from.z() ); ::glVertex3f( to.x(), to.y(), to.z() ); ::glEnd(); // resume lighting ::glEnable( GL_LIGHTING ); return; } /* Draw edges as 3D cylinders */ GLboolean lighting, colorMaterial; ::glGetBooleanv( GL_LIGHTING, &lighting ); ::glGetBooleanv( GL_COLOR_MATERIAL, &colorMaterial ); ::glEnable( GL_LIGHTING ); ::glDisable(GL_COLOR_MATERIAL); float color[4]; color[0] = clr.redF(); color[1] = clr.greenF(); color[2] = clr.blueF(); color[3] = clr.alphaF(); Vector_3 v = to - from; // compute the length of the edge // method 1: // float length = sqrt( CGAL::squared_distance( from, to ) ); // method 2: float length = sqrt( v.squared_length() ); // normalize v = v / length; // compute the angle: cos theta = v.z/1.0 GLfloat angle = acos( v.z() ) / 3.1415927 * 180; ::glPushMatrix(); // move to "from" point ::glTranslatef( from.x(), from.y(), from.z() ); // rotate from z-axis to from-->to // axis: cross product of z-axis and from-->to ::glRotatef( angle, -v.y(), v.x(), 0.0f ); // draw GLUquadricObj* quadratic = ::gluNewQuadric(); // Create A Pointer To The Quadric Object ::gluQuadricNormals( quadratic, GLU_SMOOTH ); // Create Smooth Normals ::glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color ); // gluCylinder draws a cylinder oriented along the z-axis ::gluCylinder( quadratic, r, r, length, 16, 4 ); // move back to origin ::glPopMatrix(); if ( colorMaterial ) ::glEnable( GL_COLOR_MATERIAL ); if ( !lighting ) ::glDisable( GL_LIGHTING ); }
/****************************************************************************** * Creates the geometry for a single arrow element. ******************************************************************************/ void OpenGLArrowPrimitive::createArrowElement(int index, const Point3& pos, const Vector3& dir, const ColorA& color, FloatType width) { const float arrowHeadRadius = width * 2.5f; const float arrowHeadLength = arrowHeadRadius * 1.8f; if(shadingMode() == NormalShading) { // Build local coordinate system. Vector_3<float> t, u, v; float length = dir.length(); if(length != 0) { t = dir / length; if(dir.y() != 0 || dir.x() != 0) u = Vector_3<float>(dir.y(), -dir.x(), 0); else u = Vector_3<float>(-dir.z(), 0, dir.x()); u.normalize(); v = u.cross(t); } else { t.setZero(); u.setZero(); v.setZero(); } ColorAT<float> c = color; Point_3<float> v1 = pos; Point_3<float> v2; Point_3<float> v3 = v1 + dir; float r; if(length > arrowHeadLength) { v2 = v1 + t * (length - arrowHeadLength); r = arrowHeadRadius; } else { v2 = v1; r = arrowHeadRadius * length / arrowHeadLength; } OVITO_ASSERT(_mappedVerticesWithNormals); VertexWithNormal* vertex = _mappedVerticesWithNormals + (index * _verticesPerElement); // Generate vertices for cylinder. for(int i = 0; i <= _cylinderSegments; i++) { Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v; Vector_3<float> d = n * width; vertex->pos = v1 + d; vertex->normal = n; vertex->color = c; vertex++; vertex->pos = v2 + d; vertex->normal = n; vertex->color = c; vertex++; } // Generate vertices for head cone. for(int i = 0; i <= _cylinderSegments; i++) { Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v; Vector_3<float> d = n * r; vertex->pos = v2 + d; vertex->normal = n; vertex->color = c; vertex++; vertex->pos = v3; vertex->normal = n; vertex->color = c; vertex++; } // Generate vertices for cylinder cap. for(int i = 0; i < _cylinderSegments; i++) { Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v; Vector_3<float> d = n * width; vertex->pos = v1 + d; vertex->normal = Vector_3<float>(0,0,-1); vertex->color = c; vertex++; } // Generate vertices for cone cap. for(int i = 0; i < _cylinderSegments; i++) { Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v; Vector_3<float> d = n * r; vertex->pos = v2 + d; vertex->normal = Vector_3<float>(0,0,-1); vertex->color = c; vertex++; } } else if(shadingMode() == FlatShading) { Vector_3<float> t; float length = dir.length(); if(length != 0) t = dir / length; else t.setZero(); ColorAT<float> c = color; Point_3<float> base = pos; OVITO_ASSERT(_mappedVerticesWithElementInfo); VertexWithElementInfo* vertices = _mappedVerticesWithElementInfo + (index * _verticesPerElement); if(length > arrowHeadLength) { vertices[0].pos = Point_3<float>(length, 0, 0); vertices[1].pos = Point_3<float>(length - arrowHeadLength, arrowHeadRadius, 0); vertices[2].pos = Point_3<float>(length - arrowHeadLength, width, 0); vertices[3].pos = Point_3<float>(0, width, 0); vertices[4].pos = Point_3<float>(0, -width, 0); vertices[5].pos = Point_3<float>(length - arrowHeadLength, -width, 0); vertices[6].pos = Point_3<float>(length - arrowHeadLength, -arrowHeadRadius, 0); } else { float r = arrowHeadRadius * length / arrowHeadLength; vertices[0].pos = Point_3<float>(length, 0, 0); vertices[1].pos = Point_3<float>(0, r, 0); vertices[2].pos = Point_3<float>::Origin(); vertices[3].pos = Point_3<float>::Origin(); vertices[4].pos = Point_3<float>::Origin(); vertices[5].pos = Point_3<float>::Origin(); vertices[6].pos = Point_3<float>(0, -r, 0); } for(int i = 0; i < _verticesPerElement; i++, ++vertices) { vertices->base = base; vertices->dir = t; vertices->color = c; } } }
/****************************************************************************** * Creates the geometry for a single cylinder element. ******************************************************************************/ void OpenGLArrowPrimitive::createCylinderElement(int index, const Point3& pos, const Vector3& dir, const ColorA& color, FloatType width) { if(_usingGeometryShader && (shadingMode() == FlatShading || renderingQuality() == HighQuality)) { OVITO_ASSERT(_mappedVerticesWithElementInfo); OVITO_ASSERT(_verticesPerElement == 1); VertexWithElementInfo* vertex = _mappedVerticesWithElementInfo + index; vertex->pos = vertex->base = pos; vertex->dir = dir; vertex->color = color; vertex->radius = width; return; } if(shadingMode() == NormalShading) { // Build local coordinate system. Vector_3<float> t, u, v; float length = dir.length(); if(length != 0) { t = dir / length; if(dir.y() != 0 || dir.x() != 0) u = Vector_3<float>(dir.y(), -dir.x(), 0); else u = Vector_3<float>(-dir.z(), 0, dir.x()); u.normalize(); v = u.cross(t); } else { t.setZero(); u.setZero(); v.setZero(); } ColorAT<float> c = color; Point_3<float> v1 = pos; Point_3<float> v2 = v1 + dir; if(renderingQuality() != HighQuality) { OVITO_ASSERT(_mappedVerticesWithNormals); VertexWithNormal* vertex = _mappedVerticesWithNormals + (index * _verticesPerElement); // Generate vertices for cylinder mantle. for(int i = 0; i <= _cylinderSegments; i++) { Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v; Vector_3<float> d = n * width; vertex->pos = v1 + d; vertex->normal = n; vertex->color = c; vertex++; vertex->pos = v2 + d; vertex->normal = n; vertex->color = c; vertex++; } // Generate vertices for first cylinder cap. for(int i = 0; i < _cylinderSegments; i++) { Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v; Vector_3<float> d = n * width; vertex->pos = v1 + d; vertex->normal = Vector_3<float>(0,0,-1); vertex->color = c; vertex++; } // Generate vertices for second cylinder cap. for(int i = _cylinderSegments - 1; i >= 0; i--) { Vector_3<float> n = _cosTable[i] * u + _sinTable[i] * v; Vector_3<float> d = n * width; vertex->pos = v2 + d; vertex->normal = Vector_3<float>(0,0,1); vertex->color = c; vertex++; } } else { // Create bounding box geometry around cylinder for raytracing. OVITO_ASSERT(_mappedVerticesWithElementInfo); VertexWithElementInfo* vertex = _mappedVerticesWithElementInfo + (index * _verticesPerElement); OVITO_ASSERT(_verticesPerElement == 14); u *= width; v *= width; Point3 corners[8] = { v1 - u - v, v1 - u + v, v1 + u - v, v1 + u + v, v2 - u - v, v2 - u + v, v2 + u + v, v2 + u - v }; const static size_t stripIndices[14] = { 3,2,6,7,4,2,0,3,1,6,5,4,1,0 }; for(int i = 0; i < 14; i++, vertex++) { vertex->pos = corners[stripIndices[i]]; vertex->base = v1; vertex->dir = dir; vertex->color = c; vertex->radius = width; } } } else if(shadingMode() == FlatShading) { Vector_3<float> t; float length = dir.length(); if(length != 0) t = dir / length; else t.setZero(); ColorAT<float> c = color; Point_3<float> base = pos; OVITO_ASSERT(_mappedVerticesWithElementInfo); VertexWithElementInfo* vertices = _mappedVerticesWithElementInfo + (index * _verticesPerElement); vertices[0].pos = Point_3<float>(0, width, 0); vertices[1].pos = Point_3<float>(0, -width, 0); vertices[2].pos = Point_3<float>(length, -width, 0); vertices[3].pos = Point_3<float>(length, width, 0); for(int i = 0; i < _verticesPerElement; i++, ++vertices) { vertices->base = base; vertices->dir = t; vertices->color = c; } } }
std::array<double,3> convert_to_array(const Vector_3& p) { return std::array<double,3>({p.x(),p.y(),p.z()}); }
// Génère le vecteur qui a subi une rotation d'angle teta Vector_3 DegradeAnObject::rotationVector(Vector_3 v, Vector_3 normal, double teta) { double c = cos(teta); double s = sin(teta); Kernel::RT m00 = normal.x() * normal.x() * (1-c) + c; Kernel::RT m01 = normal.x() * normal.y() * (1-c) - normal.z() * s; Kernel::RT m02 = normal.x() * normal.z() * (1-c) + normal.y() * s; Kernel::RT m10 = normal.x() * normal.y() * (1-c) + normal.z() * s; Kernel::RT m11 = normal.y() * normal.y() * (1-c) + c; Kernel::RT m12 = normal.z() * normal.y() * (1-c) - normal.x() * s; Kernel::RT m20 = normal.x() * normal.z() * (1-c) - normal.y() * s; Kernel::RT m21 = normal.z() * normal.y() * (1-c) + normal.x() * s; Kernel::RT m22 = normal.z() * normal.z() * (1-c) + c; CGAL::Aff_transformation_3<Kernel> rotate(m00, m01, m02, m10, m11, m12, m20, m21, m22); return rotate.transform(v); }
void apply_semanticRequirements(Polyhedron& exteriorPolyhe) { std::map<std::string,std::vector<bool>> semanticNormals; semanticNormals["Roof"] = std::vector<bool>(3,true); semanticNormals["Roof"][2] = false; // down semanticNormals["Ground"] = std::vector<bool>(3,false); semanticNormals["Ground"][2] = true; semanticNormals["Ceiling"] = std::vector<bool>(3,false); semanticNormals["Ceiling"][2] = true; semanticNormals["Floor"] = std::vector<bool>(3,false); semanticNormals["Floor"][0] = true; semanticNormals["Wall"] = std::vector<bool>(3,true); semanticNormals["Window"] = std::vector<bool>(3,true); semanticNormals["Door"] = std::vector<bool>(3,true); semanticNormals["Closure"] = std::vector<bool>(3,true); semanticNormals[TO_DIST_SEMANTIC] = std::vector<bool>(3,true); //semanticNormals["Anything"] = std::vector<bool>(3,true); std::map<std::string,int> semanticEnum; semanticEnum["Roof"] = 1; semanticEnum["Window"] = 2; semanticEnum["Door"] = 3; semanticEnum["Wall"] = 4; semanticEnum["Ground"] = 5; semanticEnum["Ceiling"] = 6; semanticEnum["Floor"] = 7; semanticEnum["Closure"] = 8; semanticEnum["Anything"] = 9; //semanticEnum["Install"] = 10; Vector_3 ortVec; Polyhedron::Facet_iterator exfIt; // Iterate over exterior faces for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) { int minSem = 99; for (std::vector<std::string>::iterator svIt=exfIt->equidistSems.begin();svIt!=exfIt->equidistSems.end();++svIt) { // Add equidist semantics std::map<std::string,int>::iterator seIt = semanticEnum.find(*svIt); if (seIt!=semanticEnum.end()) { // ...... if (seIt->second<minSem) { minSem = seIt->second; exfIt->semanticBLA = *svIt; } }else { // This seems wrong... exfIt->semanticBLA = *svIt; break; } } pointVector facetPoints = comp_facetPoints(exfIt); CGAL::normal_vector_newell_3(facetPoints.begin(),facetPoints.end(),ortVec); // Calculate normal vector, ortVec set to zero in newell if (!normalizeVector(ortVec)) continue; std::map<std::string,std::vector<bool>>::iterator snIt = semanticNormals.find(exfIt->semanticBLA); if (snIt!=semanticNormals.end()) { if (!snIt->second[0] && ortVec.z() > HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_UP_SEMANTIC; else if (!snIt->second[1] && ortVec.z() <= HORIZONTAL_ANGLE_RANGE && ortVec.z() >= -HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_HOR_SEMANTIC; else if (!snIt->second[2] && ortVec.z() <= -HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_DOWN_SEMANTIC; } else { if (ortVec.z() > HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_UP_SEMANTIC; else if (ortVec.z() <= HORIZONTAL_ANGLE_RANGE && ortVec.z() >= -HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_HOR_SEMANTIC; else if (ortVec.z() <= -HORIZONTAL_ANGLE_RANGE) exfIt->semanticBLA = DEFAULT_DOWN_SEMANTIC; } } // Set semantics of facets created due to closing (too far from original geometry) for (exfIt = exteriorPolyhe.facets_begin(); exfIt != exteriorPolyhe.facets_end(); ++exfIt) { if (exfIt->semanticBLA==TO_DIST_SEMANTIC) { std::set<Polyhedron::Facet_handle> fhSet; connectedSemFacets(exfIt,TO_DIST_SEMANTIC,false,fhSet); bool canBeUp = indirectlyTouchingFindSem(DEFAULT_UP_SEMANTIC,fhSet); bool canBeDown = indirectlyTouchingFindSem(DEFAULT_DOWN_SEMANTIC,fhSet); assignCeilVloor(fhSet,canBeUp,canBeDown); } } }
// Normalise un vecteur Vector_3 DegradeAnObject::normalizeVector(Vector_3 v) { double norm = sqrt(to_double(v.x() * v.x() + v.y() * v.y() + v.z() * v.z())); return v/norm; }
Point_3 Origin::operator-(const Vector_3& v) const {return Point_3( CGAL::ORIGIN-v.get_data() ); }
int Plasma::interaction(int m, int sum){ register int i, j,k; static Vector_3 r; //static Vector_3 df; int type=0; // ion-ion for(i=(m<0 ? 0 : m);i<n;i++){ for(k=0;k<3;k++){ f[i][k]=0; // reducing to elementary cell if(x[i][k]>0)xx[i][k]=amod1(x[i][k]+L/2,L)-L/2; else xx[i][k]=amod1(x[i][k]-L/2,L)+L/2; } if(m>=0)break; } Quant=Ecoul=0; double dEcoul,dEpotent,dQuant; double df; if(!is_matr || m<0)Epotent=0; for(i=0;i<(m<0 ? n : m+1);i++){ if(i>=ni)type|=0x1;// setting electron-? interaction type type&=0x1; // setting ?-ion interaction type for(j=((m<0 || i==m) ? i+1: m); j<n;j++){ if(j>=ni)type|=0x2;// setting ?-electron interaction type //r=xx[i]-xx[j]; for(k=0;k<3;k++){ // determining the closest //distance and correspondent direction r[k]=xx[i][k]-xx[j][k]; if(r[k]>L/2)r[k]-=L; if(r[k]<-L/2)r[k]+=L; } double R=r.norm(); if(R<1e-20){ printf("Got small distance (%d,%d) !\n",i,j); } r/=R; dEcoul=-1/R; if(type==ELCELC || type ==IONION){ dEcoul=-dEcoul; if(write_distr){ if(non_symm && type==IONION)DRRpp.point(R,1.); else DRRee.point(R,1.); } } else if(write_distr)DRRep.point(R,1.); df=potential(type,R,dEpotent,dQuant); ///df=PotentialKELBG(type,R,dEpotent,dQuant); //f[i]+=df; //f[j]-=df; for(k=0;k<3;k++){ // to avoid vector copying f[i][k]+=df*r[k]; f[j][k]-=df*r[k]; } Ecoul+=dEcoul; Quant+=dQuant; if(is_matr && m>=0)Epotent+=dEpotent-(*umatr)(i,j); else Epotent+=dEpotent; if(is_matr){ if(m>=0){ int l=(i< m ? i : j); (*umatr)(l,l)=(*umatr)(i,j); //(l,l) used for storing temporary //fucktmp[l]=(*umatr)(i,j); //printf("%d <- (%d, %d)[%f]\n",l,i,j,fucktmp[l]); } (*umatr)(i,j)=dEpotent; } if(m>=0 && i!=m)break; } } if(is_matr && m>=0 && sum){ Epotent=0; for(i=0;i<n;i++){ for(j=i+1;j<n;j++){ Epotent+=(*umatr)(i,j); } } } return 0; }
// Convert elemental values to nodal values. void Window_manifold_2:: elements_to_nodes( const COM::DataItem *e_vals, COM::DataItem *n_vals, const int scheme, const COM::DataItem *e_weights, COM::DataItem *n_weights, const int tosum) { COM_assertion_msg( e_vals && e_vals->is_elemental(), "First argument must be elemental dataitem"); COM_assertion_msg( n_vals && n_vals->is_nodal(), "Second argument must be nodal dataitem"); COM_assertion_msg( scheme!=E2N_USER || e_weights && e_weights->is_elemental(), "Third argument must be elemental dataitem"); COM_assertion_msg( !n_weights || n_weights->is_nodal() && COM_compatible_types(COM_DOUBLE, n_weights->data_type()), "Output weights must be nodal with double precision"); // Inherit nodal and elemental values onto the window COM::DataItem *nodal_vals; if ( n_vals->window() != _buf_window) nodal_vals = _buf_window->inherit( n_vals, "nodal_vals__E2NTEMP", false, true, NULL, 0); else nodal_vals = n_vals; const COM::DataItem *elem_vals; if ( e_vals->window() != _buf_window) elem_vals = _buf_window->inherit ( const_cast<COM::DataItem*>(e_vals), "elem_vals__E2NTEMP", false, true, NULL, 0); else elem_vals = e_vals; // Inherit nodal and elemental weights onto the window COM::DataItem *nodal_weights; if ( n_weights && n_weights->window()!=_buf_window) nodal_weights = _buf_window->inherit( n_weights, "nodal_weights__E2NTEMP", false, true, NULL, 0); else { nodal_weights = _buf_window->new_dataitem( "nodal_weights__E2NTEMP", 'n', COM_DOUBLE, 1, ""); _buf_window->resize_array( nodal_weights, NULL); } const COM::DataItem *elem_weights; if ( e_weights && e_weights->window()!=_buf_window) elem_weights = _buf_window->inherit ( const_cast<COM::DataItem*>(e_weights), "elem_weights__E2NTEMP", false, true, NULL, 0); else elem_weights = e_weights; _buf_window->init_done( false); // Initialize communicator if ( _cc==NULL) init_communicator(); int local_npanes = _cc->panes().size(); // Initialize buffer spaces for nodal weights. std::vector< Real*> weights_ptrs(local_npanes); std::vector< int> weights_strds(local_npanes); int ncomp = nodal_vals->size_of_components(); COM_assertion_msg( elem_vals->size_of_components()==ncomp, "Numbers of components must match"); for (int i=0; i<local_npanes; ++i) { int nn=_cc->panes()[i]->size_of_real_nodes(); Real *p; int strd; COM::DataItem *a = _cc->panes()[i]->dataitem(nodal_weights->id()); p = weights_ptrs[i] = reinterpret_cast<Real*>(a->pointer()); strd = weights_strds[i] = a->stride(); // Initialize values to 0. for ( int k=0; k<nn; ++k, p+=strd) *p = 0.; } Vector_3<Real> J[2]; Vector_2<Real> nc(0.5,0.5); Element_node_vectors_k_const<Point_3<Real> > ps; Element_vectors_k_const<Real> elem_vals_evk; Element_node_vectors_k<Real> nodal_vals_evk; Element_vectors_k_const<Real> elem_weights_evk; Element_node_vectors_k<Real> nodal_weights_evk; // Compute nodal sums and weights on each processor std::vector< COM::Pane*>::const_iterator it=_cc->panes().begin(); for (int i=0; i<local_npanes; ++i, ++it) { // Loop through the panes COM::Pane &pane = **it; const Point_3<Real> *pnts = reinterpret_cast<const Point_3<Real>*> (pane.coordinates()); const COM::DataItem *elem_vals_pane = pane.dataitem( elem_vals->id()); const COM::DataItem *elem_weights_pane = elem_weights ? pane.dataitem( elem_weights->id()) : NULL; COM::DataItem *nodal_vals_pane = pane.dataitem( nodal_vals->id()); // Initialize values of nodal_vals_pane to 0. for ( int d=1; d<=ncomp; ++d) { COM::DataItem *nvpi = ncomp==1?nodal_vals_pane:(nodal_vals_pane+d); Real *p=reinterpret_cast<Real*>(nvpi->pointer()); for ( int j=0,s=nvpi->stride(),n=nvpi->size_of_real_items()*s; j<n; j+=s) p[j] = 0.; } // Loop through the elements of the pane Element_node_enumerator ene( &pane, 1); for ( int j=pane.size_of_real_elements(); j>0; --j, ene.next()) { ps.set( pnts, ene, 1); elem_vals_evk.set( elem_vals_pane, ene); nodal_vals_evk.set( nodal_vals_pane, ene); nodal_weights_evk.set( weights_ptrs[i], ene, weights_strds[i]); int ne=ene.size_of_edges(); int nn=ene.size_of_nodes(); Real w = 1.; switch ( scheme) { case E2N_USER: case E2N_AREA: if ( scheme == E2N_USER) { // Use user specified weights. elem_weights_evk.set( elem_weights_pane, ene); w = elem_weights_evk[0]; } // Continue to the case of E2N_ONE else { Generic_element_2 e(ne, nn); e.Jacobian( ps, nc, J); const Vector_3<Real> v = Vector_3<Real>::cross_product( J[0], J[1]); w = std::sqrt(v.squared_norm()); if ( ne==3) w*=0.5; } // Continue to the case of E2N_ONE case E2N_ONE: { // Update nodal weights for ( int k=0; k<nn; ++k) nodal_weights_evk[k] += w; // Update nodal sums for ( int d=0; d<ncomp; ++d) { Real t = w*elem_vals_evk(0,d); for ( int k=0; k<nn; ++k) nodal_vals_evk(k,d) += t; } break; } case E2N_ANGLE: case E2N_SPHERE: { for ( int k=0; k<ne; ++k) { J[0] = ps[k==ne-1?0:k+1]-ps[k]; J[1] = ps[k?k-1:ne-1]-ps[k]; double s = std::sqrt((J[0]*J[0])*(J[1]*J[1])); if ( s>0) { double cosw = J[0]*J[1]/s; if (cosw>1) cosw=1; else if ( cosw<-1) cosw=-1; w = std::acos( cosw); if ( scheme==SURF::E2N_SPHERE) w = std::sin(w)/s; // Update nodal weights nodal_weights_evk[k] += w; // Update nodal sums for ( int d=0; d<ncomp; ++d) nodal_vals_evk(k,d) += w*elem_vals_evk(0,d); } } for ( int k=ne; k<nn; ++k) { // Update nodal weights nodal_weights_evk[k] += 1; // Update nodal sums for ( int d=0; d<ncomp; ++d) nodal_vals_evk(k,d) += elem_vals_evk(0,d); } break; } default: COM_assertion_msg(false, "Should never reach here"); } } } // Performan reductions on shared nodes for nodal sums reduce_on_shared_nodes( nodal_vals, OP_SUM); // Performan reductions on shared nodes for nodal weights _cc->init( &(void*&)weights_ptrs[0], COM_DOUBLE, 1, NULL, NULL); _cc->begin_update_shared_nodes(); _cc->reduce_on_shared_nodes( MPI_SUM); _cc->end_update_shared_nodes(); if ( !tosum) { // Divide nodal sums by weights on each processor it=_cc->panes().begin(); for (int i=0; i<local_npanes; ++i, ++it) { // Loop through the panes COM::Pane &pane = **it; COM::DataItem *nodal_vals_pane = pane.dataitem( nodal_vals->id()); for ( int d=1; d<=ncomp; ++d) { COM::DataItem *nvpi = ncomp==1?nodal_vals_pane:(nodal_vals_pane+d); Real *v=reinterpret_cast<Real*>(nvpi->pointer()); Real *w = weights_ptrs[i]; for ( int j=0,js=nvpi->stride(),n=nvpi->size_of_real_items()*js, k=0, ks=weights_strds[i]; j<n; j+=js, k+=ks) { if ( w[k]==0) { std::cout << "***Rocsurf Error: Got zero weight for node " << j+1 << " in pane " << pane.id() << std::endl; } if ( w[k] == 0) v[j] = 0; else v[j] /= w[k]; } } } } // Delete the temporary dataitems in reverse order. if ( elem_weights != e_weights) _buf_window->delete_dataitem( elem_weights->name()); _buf_window->delete_dataitem( nodal_weights->name()); if ( elem_vals != e_vals) _buf_window->delete_dataitem( elem_vals->name()); if (nodal_vals != n_vals) _buf_window->delete_dataitem( nodal_vals->name()); _buf_window->init_done( false); }