vector<Segment> Shape::getCutlines(const Matrix4d &T, double z, vector<Vector2d> &vertices, double &max_gradient, vector<Triangle> &support_triangles, double supportangle, double thickness) const { Vector2d lineStart; Vector2d lineEnd; vector<Segment> lines; // we know our own tranform: Matrix4d transform = T * transform3D.transform ; int count = (int)triangles.size(); // #ifdef _OPENMP // #pragma omp parallel for schedule(dynamic) // #endif for (int i = 0; i < count; i++) { Segment line(-1,-1); int num_cutpoints = triangles[i].CutWithPlane(z, transform, lineStart, lineEnd); if (num_cutpoints == 0) { if (supportangle >= 0 && thickness > 0) { if (triangles[i].isInZrange(z-thickness, z, transform)) { const double slope = -triangles[i].slopeAngle(transform); if (slope >= supportangle) { support_triangles.push_back(triangles[i].transformed(transform)); } } } continue; } if (num_cutpoints > 0) { int havev = find_vertex(vertices, lineStart); if (havev >= 0) line.start = havev; else { line.start = vertices.size(); vertices.push_back(lineStart); } if (abs(triangles[i].Normal.z()) > max_gradient) max_gradient = abs(triangles[i].Normal.z()); if (supportangle >= 0) { const double slope = -triangles[i].slopeAngle(transform); if (slope >= supportangle) support_triangles.push_back(triangles[i].transformed(transform)); } } if (num_cutpoints > 1) { int havev = find_vertex(vertices, lineEnd); if (havev >= 0) line.end = havev; else { line.end = vertices.size(); vertices.push_back(lineEnd); } } // Check segment normal against triangle normal. Flip segment, as needed. if (line.start != -1 && line.end != -1 && line.end != line.start) { // if we found a intersecting triangle Vector3d Norm = triangles[i].transformed(transform).Normal; Vector2d triangleNormal = Vector2d(Norm.x(), Norm.y()); Vector2d segment = (lineEnd - lineStart); Vector2d segmentNormal(-segment.y(),segment.x()); triangleNormal.normalize(); segmentNormal.normalize(); if( (triangleNormal-segmentNormal).squared_length() > 0.2){ // if normals do not align, flip the segment int iswap=line.start;line.start=line.end;line.end=iswap; } // cerr << "line "<<line.start << "-"<<line.end << endl; lines.push_back(line); } } return lines; }
void UIGeom::render(RenderDevice* rd, float lineScale) { if (! visible) { return; } if (m_twoSidedPolys) { rd->setCullFace(RenderDevice::CULL_NONE); rd->enableTwoSidedLighting(); } for (int i = 0; i < poly3D.size(); ++i) { const ConvexPolygon& poly = poly3D[i]; rd->beginPrimitive(RenderDevice::TRIANGLE_FAN); rd->setNormal(poly.normal()); for (int v = 0; v < poly.numVertices(); ++v) { rd->sendVertex(poly.vertex(v)); } rd->endPrimitive(); } // Per segment normals Array<Vector3> normal; const Vector3 eye = computeEye(rd); for (int i = 0; i < line3D.size(); ++i) { const PolyLine& line = line3D[i]; // Compute one normal for each segement normal.resize(line.numSegments(), false); for (int s = 0; s < line.numSegments(); ++s) { normal[s] = segmentNormal(line.segment(s), eye); } bool closed = line.closed(); // Compute line width { Vector4 v = rd->project(line.vertex(0)); float L = 2; if (v.w > 0) { L = min(15.0f * v.w, 10.0f); } else { L = 10.0f; } rd->setLineWidth(L * lineScale); } bool colorWrite = rd->colorWrite(); bool depthWrite = rd->depthWrite(); // Draw lines twice. The first time we draw color information // but do not set the depth buffer. The second time we write // to the depth buffer; this prevents line strips from // corrupting their own antialiasing with depth conflicts at // the line joint points. if (colorWrite) { rd->setDepthWrite(false); rd->beginPrimitive(RenderDevice::LINE_STRIP); for (int v = 0; v < line.numVertices(); ++v) { // Compute the smooth normal. If we have a non-closed // polyline, the ends are special cases. Vector3 N; if (! closed && (v == 0)) { N = normal[0]; } else if (! closed && (v == line.numVertices())) { N = normal.last(); } else { // Average two adjacent normals N = normal[v % normal.size()] + normal[(v - 1) % normal.size()]; } if (N.squaredLength() < 0.05) { // Too small to normalize; revert to the // nearest segment normal rd->setNormal(normal[iMin(v, normal.size() - 1)]); } else { rd->setNormal(N.direction()); } rd->sendVertex(line.vertex(v)); } rd->endPrimitive(); } if (depthWrite) { rd->setColorWrite(false); rd->setDepthWrite(true); rd->beginPrimitive(RenderDevice::LINE_STRIP); for (int v = 0; v < line.numVertices(); ++v) { rd->sendVertex(line.vertex(v)); } rd->endPrimitive(); } rd->setColorWrite(colorWrite); rd->setDepthWrite(depthWrite); } }