static CVertex unrotated_vertex(const CVertex &v) { if(v.m_type) { return CVertex(v.m_type, unrotated_point(v.m_p), unrotated_point(v.m_c)); } return CVertex(v.m_type, unrotated_point(v.m_p), Point(0, 0)); }
static void zigzag(const CArea &input_a) { if(input_a.m_curves.size() == 0) { CArea::m_processing_done += CArea::m_single_area_processing_length; return; } one_over_units = 1 / CArea::m_units; CArea a(input_a); rotate_area(a); CBox2D b; a.GetBox(b); double x0 = b.MinX() - 1.0; double x1 = b.MaxX() + 1.0; double height = b.MaxY() - b.MinY(); int num_steps = int(height / stepover_for_pocket + 1); double y = b.MinY();// + 0.1 * one_over_units; Point null_point(0, 0); rightward_for_zigs = true; if(CArea::m_please_abort)return; double step_percent_increment = 0.8 * CArea::m_single_area_processing_length / num_steps; for(int i = 0; i<num_steps; i++) { double y0 = y; y = y + stepover_for_pocket; Point p0(x0, y0); Point p1(x0, y); Point p2(x1, y); Point p3(x1, y0); CCurve c; c.m_vertices.push_back(CVertex(0, p0, null_point, 0)); c.m_vertices.push_back(CVertex(0, p1, null_point, 0)); c.m_vertices.push_back(CVertex(0, p2, null_point, 1)); c.m_vertices.push_back(CVertex(0, p3, null_point, 0)); c.m_vertices.push_back(CVertex(0, p0, null_point, 1)); CArea a2; a2.m_curves.push_back(c); a2.Intersect(a); make_zig(a2, y0, y); rightward_for_zigs = !rightward_for_zigs; if(CArea::m_please_abort)return; CArea::m_processing_done += step_percent_increment; } reorder_zigs(); CArea::m_processing_done += 0.2 * CArea::m_single_area_processing_length; }
vector< vector<CVertex> > CSXFMap::s_height_map::load(const string fname) { unsigned v, u; pnts.clear(); #ifdef EMBEDDED // Ограничение - только для МГК header.width = 1000; header.height = 1000; for(v = 0; v < header.height; v++) { vector<CVertex> row; for(u = 0; u < header.width; u++) row.push_back(CVertex(u, v, 100)); pnts.push_back(row); } #else unsigned t, elem_num; float * p_buf; shared_ptr<float> buf; CFile fl(fname); fl(& header, sizeof(header)); unpack_header(); check(); elem_num = header.height * header.width; buf.reset(new float[elem_num], std::default_delete<float[]>()); p_buf = buf.get(); throw_null(p_buf); fl(p_buf, elem_num * sizeof(float)); CFile::unpack<float>(p_buf, elem_num); for(u = 0, t = 0; u < header.width; u++) { vector<CVertex> col; for(v = 0; v < header.height; v++, t++) col.push_back(CVertex(u, v, p_buf[t])); pnts.push_back(col); } #endif return pnts; }
bool IsInside(const Point& p, const CArea& a) { CArea a2; CCurve c; c.m_vertices.push_back(CVertex(Point(p.x - 0.01, p.y - 0.01))); c.m_vertices.push_back(CVertex(Point(p.x + 0.01, p.y - 0.01))); c.m_vertices.push_back(CVertex(Point(p.x + 0.01, p.y + 0.01))); c.m_vertices.push_back(CVertex(Point(p.x - 0.01, p.y + 0.01))); c.m_vertices.push_back(CVertex(Point(p.x - 0.01, p.y - 0.01))); a2.m_curves.push_back(c); a2.Intersect(a); if(fabs(a2.GetArea()) < 0.0004)return false; return true; }
CPolygon::CPolygon( CModelSurface *surface,const CPlane &plane,const CBox &box ): _surface(surface), _plane(plane){ CVec3 v[4]; if( fabs(plane.n.x)>fabs(plane.n.y) && fabs(plane.n.x)>fabs(plane.n.z) ){ if( plane.n.x>0 ){ v[0]=box.Corner(3);v[1]=box.Corner(7);v[2]=box.Corner(5);v[3]=box.Corner(1); }else{ v[0]=box.Corner(6);v[1]=box.Corner(2);v[2]=box.Corner(0);v[3]=box.Corner(4); } for( int i=0;i<4;++i ) v[i].x=plane.SolveX( v[i].y,v[i].z ); }else if( fabs(plane.n.y)>fabs(plane.n.z) ){ if( plane.n.y>0 ){ v[0]=box.Corner(6);v[1]=box.Corner(7);v[2]=box.Corner(3);v[3]=box.Corner(2); }else{ v[0]=box.Corner(0);v[1]=box.Corner(1);v[2]=box.Corner(5);v[3]=box.Corner(4); } for( int i=0;i<4;++i ) v[i].y=plane.SolveY( v[i].x,v[i].z ); }else{ if( plane.n.z>0 ){ v[0]=box.Corner(7);v[1]=box.Corner(6);v[2]=box.Corner(4);v[3]=box.Corner(5); }else{ v[0]=box.Corner(2);v[1]=box.Corner(3);v[2]=box.Corner(1);v[3]=box.Corner(0); } for( int i=0;i<4;++i ) v[i].z=plane.SolveZ( v[i].x,v[i].y ); } for( int i=0;i<4;++i ){ CVertex tv=CVertex( v[i] ); AddVertex( tv ); } }
double CCurve::PointToPerim(const Point& p)const { double best_dist = 0.0; double perim_at_best_dist = 0.0; //Point best_point = Point(0, 0); bool best_dist_found = false; double perim = 0.0; const Point *prev_p = NULL; bool first_span = true; for(std::list<CVertex>::const_iterator It = m_vertices.begin(); It != m_vertices.end(); It++) { const CVertex& vertex = *It; if(prev_p) { Span span(*prev_p, vertex, first_span); Point near_point = span.NearestPoint(p); first_span = false; double dist = near_point.dist(p); if(!best_dist_found || dist < best_dist) { best_dist = dist; Span span_to_point(*prev_p, CVertex(span.m_v.m_type, near_point, span.m_v.m_c)); perim_at_best_dist = perim + span_to_point.Length(); best_dist_found = true; } perim += span.Length(); } prev_p = &(vertex.m_p); } return perim_at_best_dist; }
void CCurve::OffsetForward(double forwards_value, bool refit_arcs) { // for drag-knife compensation // replace arcs with lines UnFitArcs(); std::list<Span> spans; GetSpans(spans); m_vertices.clear(); // shift all the spans for(std::list<Span>::iterator It = spans.begin(); It != spans.end(); It++) { Span &span = *It; Point v = span.GetVector(0.0); v.normalize(); Point shift = v * forwards_value; span.m_p = span.m_p + shift; span.m_v.m_p = span.m_v.m_p + shift; } // loop through the shifted spans for(std::list<Span>::iterator It = spans.begin(); It != spans.end();) { Span &span = *It; Point v = span.GetVector(0.0); v.normalize(); // add the span if(It == spans.begin())m_vertices.push_back(span.m_p); m_vertices.push_back(span.m_v.m_p); It++; if(It != spans.end()) { Span &next_span = *It; Point nv = next_span.GetVector(0.0); nv.normalize(); double sin_angle = v ^ nv; bool sharp_corner = ( fabs(sin_angle) > 0.5 ); // angle > 30 degrees if(sharp_corner) { // add an arc to the start of the next span int arc_type = ((sin_angle > 0) ? 1 : (-1)); Point centre = span.m_v.m_p - v * forwards_value; m_vertices.push_back(CVertex(arc_type, next_span.m_p, centre)); } } } if(refit_arcs) FitArcs(); // find the arcs again else UnFitArcs(); // convert those little arcs added to lines }
void ClipMesh::processEdges() { const size_t numEdges = _edges.size(); for( size_t currEdge = 0; currEdge < numEdges; ++currEdge ) { CEdge& edge = _edges[currEdge]; if( !edge.visible ) { continue; } const int v0 = edge.vertex[0]; const int v1 = edge.vertex[1]; const int f0 = edge.faces[0]; const int f1 = edge.faces[1]; CFace& face0 = _faces[f0]; CFace& face1 = _faces[f1]; const float d0 = _vertices[v0].distance; const float d1 = _vertices[v1].distance; if( d0 <= 0.0f && d1 <= 0.0f ) { face0.edges.erase(currEdge); if( face0.edges.empty() ) { face0.visible = false; } face1.edges.erase(currEdge); if( face1.edges.empty() ) { face1.visible = false; } edge.visible = false; continue; } // face is on nonnegative side and retains the edge if( d0 >= 0.0f && d1 >= 0.0f ) { continue; } // the edge is split by the plane. copmute the point of intersection. // if the old edge is <v0,v1> and i is the intersection point, // the new edge is <v0,i> when d0 > 0, or<i,v1> when d1 > 0. const size_t vNew = _vertices.size(); _vertices.push_back(CVertex()); CVertex& vertexNew = _vertices[vNew]; const cc::Vec3f p0 = _vertices[edge.vertex[0]].point; const cc::Vec3f p1 = _vertices[edge.vertex[1]].point; vertexNew.point = p0 + (d0/(d0 - d1))*(p1 - p0); if( d0 > 0.0f ) { edge.vertex[1] = vNew; } else { edge.vertex[0] = vNew; } } }
void CCurve::AddArcOrLines(bool check_for_arc, std::list<CVertex> &new_vertices, std::list<const CVertex*>& might_be_an_arc, CArc &arc, bool &arc_found, bool &arc_added) { if(check_for_arc && CheckForArc(new_vertices.back(), might_be_an_arc, arc)) { arc_found = true; } else { if(arc_found) { if(arc.AlmostALine()) { new_vertices.push_back(CVertex(arc.m_e, arc.m_user_data)); } else { new_vertices.push_back(CVertex(arc.m_dir ? 1:-1, arc.m_e, arc.m_c, arc.m_user_data)); } arc_added = true; arc_found = false; const CVertex* back_vt = might_be_an_arc.back(); might_be_an_arc.clear(); if(check_for_arc)might_be_an_arc.push_back(back_vt); } else { const CVertex* back_vt = might_be_an_arc.back(); if(check_for_arc)might_be_an_arc.pop_back(); for(std::list<const CVertex*>::iterator It = might_be_an_arc.begin(); It != might_be_an_arc.end(); It++) { const CVertex* v = *It; if(It != might_be_an_arc.begin() || (new_vertices.size() == 0) || (new_vertices.back().m_p != v->m_p)) { new_vertices.push_back(*v); } } might_be_an_arc.clear(); if(check_for_arc)might_be_an_arc.push_back(back_vt); } } }
void AreaDxfRead::OnReadVertex(const double* s, const CVertex& v) { bool reverse_span = false; if(m_curve) { bool is_touching = false; if(touching(s, m_previous_end)) { is_touching = true; } else if(touching(v.m_p, m_previous_end)) { is_touching = true; reverse_span = true; } // if end point touching if(!is_touching) { // add curve m_area->m_curves.push_back(*m_curve); m_curve = NULL; } } if(m_curve == NULL) { // start a new curve m_curve = new CCurve(); m_curve->m_vertices.push_back(CVertex(0, s[0], s[1], 0, 0)); } // add to curve if(reverse_span)m_curve->m_vertices.push_back(CVertex(-v.m_type, s[0], s[1], v.m_c[0], v.m_c[1])); else m_curve->m_vertices.push_back(v); // remember end point memcpy(m_previous_end, v.m_p, 2*sizeof(double)); }
static CArea make_obround(const Point& p0, const Point& p1, double radius) { Point dir = p1 - p0; double d = dir.length(); dir.normalize(); Point right(dir.y, -dir.x); CArea obround; CCurve c; if(fabs(radius) < 0.0000001)radius = (radius > 0.0) ? 0.002 : (-0.002); Point vt0 = p0 + right * radius; Point vt1 = p1 + right * radius; Point vt2 = p1 - right * radius; Point vt3 = p0 - right * radius; c.append(vt0); c.append(vt1); c.append(CVertex(1, vt2, p1)); c.append(vt3); c.append(CVertex(1, vt0, p0)); obround.append(c); return obround; }
static CCurve MakeCCurve(const geoff_geometry::Kurve& k) { CCurve c; int n = k.nSpans(); for(int i = 0; i<= n; i++) { geoff_geometry::spVertex spv; k.Get(i, spv); c.append(CVertex(spv.type, Point(spv.p.x, spv.p.y), Point(spv.pc.x, spv.pc.y))); } return c; }
void CCurve::operator+=(const CCurve& curve) { for(std::list<CVertex>::const_iterator It = curve.m_vertices.begin(); It != curve.m_vertices.end(); It++) { const CVertex &vt = *It; if(It == curve.m_vertices.begin()) { if((m_vertices.size() == 0) || (It->m_p != m_vertices.back().m_p)) { m_vertices.push_back(CVertex(It->m_p)); } } else { m_vertices.push_back(vt); } } }
// Find Coarse Edges list<CVertex> CMeshCreation::InitPolygon(list<CVertex> pList) { mEdgeLength = 0.05f; CVertex st = *pList.begin(); dt.insert(Point2(st.mPos[0], st.mPos[1])); CVertex ed; m2DMesh.mVertexList.push_back(st); for (list<CVertex>::iterator it = pList.begin(); it != pList.end(); it++) { ed = *it; float len = (ed.mPos[0] - st.mPos[0])*(ed.mPos[0] - st.mPos[0]) + (ed.mPos[1] - st.mPos[1])*(ed.mPos[1] - st.mPos[1]); if (len > mEdgeLength*mEdgeLength) { m2DMesh.mVertexList.push_back(CVertex(ed)); m2DMesh.mEdgeList.push_back(CEdge(m2DMesh.mVertexList.size() - 1, m2DMesh.mVertexList.size())); Point2 p0(st.mPos[0], st.mPos[1]); Point2 p1(ed.mPos[0], ed.mPos[1]); dt.insert(p1); vSegments.push_back(Segment2(p0, p1)); st = ed; } } // st + ed st = *pList.begin(); ed = m2DMesh.mVertexList.back(); m2DMesh.mVertexList.push_back(st); Point2 p0(st.mPos[0], st.mPos[1]); Point2 p1(ed.mPos[0], ed.mPos[1]); //dt.insert(p0); vSegments.push_back(Segment2(p1, p0)); return m2DMesh.mVertexList; }
void AreaDxfRead::OnReadArc(const double* s, const double* e, const double* c, bool dir, bool undoably) { OnReadVertex(s, CVertex(dir? 1:-1, e[0], e[1], c[0], c[1])); }
void AreaDxfRead::OnReadLine(const double* s, const double* e, bool undoably) { OnReadVertex(s, CVertex(0, e[0], e[1], 0, 0)); }
static Span MakeCSpan(const geoff_geometry::Span &sp) { return Span(Point(sp.p0.x, sp.p0.y), CVertex(sp.dir, Point(sp.p1.x, sp.p1.y), Point(sp.pc.x, sp.pc.y))); }
void CMarchCube::SingleMaterialMultiColor(CMesh* pMeshOut, CArray3Df* pArray, CArray3Df* rColorArray, CArray3Df* gColorArray, CArray3Df* bColorArray, float Thresh, float Scale) { std::vector<CArray3Df> tmpVec; //put in an stl vector to call MultiMaterial() tmpVec.push_back(*pArray); //of course, assumes cubic structure!!! GRIDCELL GridCell; pMeshOut->Clear(); //innefficient! CArray3Df Padded; CArray3Df aR; CArray3Df aG; CArray3Df aB; Padded.IniSpace(pArray->GetXSize()+2, pArray->GetYSize()+2, pArray->GetZSize()+2, -1e6); aR.IniSpace(Padded.GetXSize(), Padded.GetYSize(), Padded.GetZSize(), 0.0); aG.IniSpace(Padded.GetXSize(), Padded.GetYSize(), Padded.GetZSize(), 0.0); aB.IniSpace(Padded.GetXSize(), Padded.GetYSize(), Padded.GetZSize(), 0.0); for (int i=0; i<pArray->GetXSize(); i++) for (int j=0; j<pArray->GetYSize(); j++) for (int k=0; k<pArray->GetZSize(); k++){ //existince array Padded(i+1, j+1, k+1) = (*pArray)(i,j,k); //color arrays aR(i+1, j+1, k+1) = (*rColorArray)(i,j,k); aG(i+1, j+1, k+1) = (*gColorArray)(i,j,k); aB(i+1, j+1, k+1) = (*bColorArray)(i,j,k); } //form cubes float ai, aj, ak; //jmc: for speed, declare them only once for (int i=0; i<Padded.GetXSize()-1; i++){ for (int j=0; j<Padded.GetYSize()-1; j++){ for (int k=0; k<Padded.GetZSize()-1; k++){ ai = i-0.5f; aj = j-0.5f; ak = k-0.5f; GridCell.p[0] = CVertex(Vec3D<>(Scale*ai, Scale*aj, Scale*ak), CColor(aR(i, j, k), aG(i, j, k), aB(i, j, k))); //put in ccppn-generated rgb here. GridCell.val[0] = Padded(i, j, k); GridCell.p[1] = CVertex(Vec3D<>(Scale*(ai+1), Scale*aj, Scale*ak), CColor(aR(i+1, j, k), aG(i+1, j, k), aB(i+1, j, k))); GridCell.val[1] = Padded(i+1, j, k); GridCell.p[2] = CVertex(Vec3D<>(Scale*(ai+1), Scale*(aj+1), Scale*ak), CColor(aR(i+1, j+1, k), aG(i+1, j+1, k), aB(i+1, j+1, k))); GridCell.val[2] = Padded(i+1, j+1, k); GridCell.p[3] = CVertex(Vec3D<>(Scale*ai, Scale*(aj+1), Scale*ak), CColor(aR(i, j+1, k), aG(i, j+1, k), aB(i, j+1, k))); GridCell.val[3] = Padded(i, j+1, k); GridCell.p[4] = CVertex(Vec3D<>(Scale*ai, Scale*aj, Scale*(ak+1)), CColor(aR(i, j, k+1), aG(i, j, k+1), aB(i, j, k+1))); GridCell.val[4] = Padded(i, j, k+1); GridCell.p[5] = CVertex(Vec3D<>(Scale*(ai+1), Scale*aj, Scale*(ak+1)), CColor(aR(i+1, j, k+1), aG(i+1, j, k+1), aB(i+1, j, k+1))); GridCell.val[5] = Padded(i+1, j, k+1); GridCell.p[6] = CVertex(Vec3D<>(Scale*(ai+1), Scale*(aj+1), Scale*(ak+1)), CColor(aR(i+1, j+1, k+1), aG(i+1, j+1, k+1), aB(i+1, j+1, k+1))); GridCell.val[6] = Padded(i+1, j+1, k+1); GridCell.p[7] = CVertex(Vec3D<>(Scale*ai, Scale*(aj+1), Scale*(ak+1)), CColor(aR(i, j+1, k+1), aG(i, j+1, k+1), aB(i, j+1, k+1))); GridCell.val[7] = Padded(i, j+1, k+1); Polygonise(GridCell, Thresh, pMeshOut); //crunch this cube and add the vertices... } } } pMeshOut->WeldClose(Scale/2); }
void CCurve::ChangeStart(const Point &p) { CCurve new_curve; bool started = false; bool finished = false; int start_span = 0; bool closed = IsClosed(); for(int i = 0; i < (closed ? 2:1); i++) { const Point *prev_p = NULL; int span_index = 0; for(std::list<CVertex>::const_iterator VIt = m_vertices.begin(); VIt != m_vertices.end() && !finished; VIt++) { const CVertex& vertex = *VIt; if(prev_p) { Span span(*prev_p, vertex); if(span.On(p)) { if(started) { if(p == *prev_p || span_index != start_span) { new_curve.m_vertices.push_back(vertex); } else { if(p == vertex.m_p)new_curve.m_vertices.push_back(vertex); else { CVertex v(vertex); v.m_p = p; new_curve.m_vertices.push_back(v); } finished = true; } } else { new_curve.m_vertices.push_back(CVertex(p)); started = true; start_span = span_index; if(p != vertex.m_p)new_curve.m_vertices.push_back(vertex); } } else { if(started) { new_curve.m_vertices.push_back(vertex); } } span_index++; } prev_p = &(vertex.m_p); } } if(started) { *this = new_curve; } }
void CCurve::FitArcs(bool retry) { std::list<CVertex> new_vertices; std::list<const CVertex*> might_be_an_arc; CArc arc; bool arc_found = false; bool arc_added = false; int i = 0; for(std::list<CVertex>::iterator It = m_vertices.begin(); It != m_vertices.end(); It++, i++) { CVertex& vt = *It; if(vt.m_type || i == 0) { if (i != 0) { AddArcOrLines(false, new_vertices, might_be_an_arc, arc, arc_found, arc_added); } new_vertices.push_back(vt); } else { might_be_an_arc.push_back(&vt); if(might_be_an_arc.size() == 1) { } else { AddArcOrLines(true, new_vertices, might_be_an_arc, arc, arc_found, arc_added); } } } if(might_be_an_arc.size() > 0) { // check if the last edge can form an arc with the starting edge if(!retry && !arc_found && m_vertices.size()>2 && m_vertices.begin()->m_type==0 && IsClosed()) { std::list<const CVertex*> tmp; auto it = m_vertices.begin(); tmp.push_back(&(*it++)); tmp.push_back(&(*it)); CArc tmpArc; if(CheckForArc(new_vertices.back(),tmp,tmpArc)) { m_vertices.push_front(CVertex(new_vertices.back().m_p)); m_vertices.pop_back(); FitArcs(true); return; } } AddArcOrLines(false, new_vertices, might_be_an_arc, arc, arc_found, arc_added); } if(arc_added) { m_vertices.clear(); for(std::list<CVertex>::iterator It = new_vertices.begin(); It != new_vertices.end(); It++)m_vertices.push_back(*It); for(std::list<const CVertex*>::iterator It = might_be_an_arc.begin(); It != might_be_an_arc.end(); It++)m_vertices.push_back(*(*It)); } }
void GetCurveItem::GetCurve(CCurve& output) { // walk around the curve adding spans to output until we get to an inner's point_on_parent // then add a line from the inner's point_on_parent to inner's start point, then GetCurve from inner // add start point if(CArea::m_please_abort)return; output.m_vertices.insert(this->EndIt, CVertex(curve_tree->curve.m_vertices.front())); std::list<CurveTree*> inners_to_visit; for(std::list<CurveTree*>::iterator It2 = curve_tree->inners.begin(); It2 != curve_tree->inners.end(); It2++) { inners_to_visit.push_back(*It2); } const CVertex* prev_vertex = NULL; for(std::list<CVertex>::iterator It = curve_tree->curve.m_vertices.begin(); It != curve_tree->curve.m_vertices.end(); It++) { const CVertex& vertex = *It; if(prev_vertex) { Span span(prev_vertex->m_p, vertex); // order inners on this span std::multimap<double, CurveTree*> ordered_inners; for(std::list<CurveTree*>::iterator It2 = inners_to_visit.begin(); It2 != inners_to_visit.end();) { CurveTree *inner = *It2; double t; if(span.On(inner->point_on_parent, &t)) { ordered_inners.insert(std::make_pair(t, inner)); It2 = inners_to_visit.erase(It2); } else { It2++; } if(CArea::m_please_abort)return; } if(CArea::m_please_abort)return; for(std::multimap<double, CurveTree*>::iterator It2 = ordered_inners.begin(); It2 != ordered_inners.end(); It2++) { CurveTree& inner = *(It2->second); if(inner.point_on_parent.dist(back().m_p) > 0.01/CArea::m_units) { output.m_vertices.insert(this->EndIt, CVertex(vertex.m_type, inner.point_on_parent, vertex.m_c)); } if(CArea::m_please_abort)return; // vertex add after GetCurve std::list<CVertex>::iterator VIt = output.m_vertices.insert(this->EndIt, CVertex(inner.point_on_parent)); //inner.GetCurve(output); GetCurveItem::to_do_list.push_back(GetCurveItem(&inner, VIt)); } if(back().m_p != vertex.m_p)output.m_vertices.insert(this->EndIt, vertex); } prev_vertex = &vertex; } if(CArea::m_please_abort)return; for(std::list<CurveTree*>::iterator It2 = inners_to_visit.begin(); It2 != inners_to_visit.end(); It2++) { CurveTree &inner = *(*It2); if(inner.point_on_parent != back().m_p) { output.m_vertices.insert(this->EndIt, CVertex(inner.point_on_parent)); } if(CArea::m_please_abort)return; // vertex add after GetCurve std::list<CVertex>::iterator VIt = output.m_vertices.insert(this->EndIt, CVertex(inner.point_on_parent)); //inner.GetCurve(output); GetCurveItem::to_do_list.push_back(GetCurveItem(&inner, VIt)); } }
{ Point &pt = *It; if(pts.size() == 0) { pts.push_back(pt); } else { if(pt != pts.back())pts.push_back(pt); } } } } const Point Span::null_point = Point(0, 0); const CVertex Span::null_vertex = CVertex(Point(0, 0)); Span::Span():m_start_span(false), m_p(null_point), m_v(null_vertex){} Point Span::NearestPointNotOnSpan(const Point& p)const { if(m_v.m_type == 0) { Point Vs = (m_v.m_p - m_p); Vs.normalize(); double dp = (p - m_p) * Vs; return (Vs * dp) + m_p; } else { double radius = m_p.dist(m_v.m_c);
void CMarchCube::MultiMaterial(CMesh* pMeshOut, void* pArrays, bool SumMat, CColor* pColors, float Thresh, float Scale) { std::vector<CArray3Df>* pDA = (std::vector<CArray3Df>*) pArrays; int NumMat = (*pDA).size(); int Resolution=1; Scale=Scale/Resolution; //of course, assumes cubic structure!!! GRIDCELL GridCell; pMeshOut->Clear(); //innefficient! CArray3Df Padded; CArray3Df aR; CArray3Df aG; CArray3Df aB; Padded.IniSpace(((*pDA)[0].GetXSize()*Resolution)+2, ((*pDA)[0].GetYSize()*Resolution)+2, ((*pDA)[0].GetZSize()*Resolution)+2, 0); aR.IniSpace(Padded.GetXSize()*Resolution, Padded.GetYSize()*Resolution, Padded.GetZSize()*Resolution, 0.0); aG.IniSpace(Padded.GetXSize()*Resolution, Padded.GetYSize()*Resolution, Padded.GetZSize()*Resolution, 0.0); aB.IniSpace(Padded.GetXSize()*Resolution, Padded.GetYSize()*Resolution, Padded.GetZSize()*Resolution, 0.0); for (int i=0; i<(*pDA)[0].GetXSize()*Resolution; i++) for (int j=0; j<(*pDA)[0].GetYSize()*Resolution; j++) for (int k=0; k<(*pDA)[0].GetZSize()*Resolution; k++){ //find the max, for color (or for thresh, as well if !SumMat) float max = -9e9f; // float max = 0.0f; for (int m=0; m<NumMat; m++){ if ((*pDA)[m](i, j, k) > max){ max = (*pDA)[m](i, j, k); if (pColors != NULL){ //grab the colors! aR(i+1, j+1, k+1) = pColors[m].r; aG(i+1, j+1, k+1) = pColors[m].g; aB(i+1, j+1, k+1) = pColors[m].b; //fill in outside of padded here if we wish... } } } if (SumMat){ //if we're summing the materials to create the mesh... for (int m=0; m<NumMat; m++){ float ToAdd = ((*pDA)[m])(i, j, k); if (m==0) Padded(i+1, j+1, k+1) = ToAdd; else Padded(i+1, j+1, k+1) += ToAdd; } } else { //if we're not summing the materials... Padded(i+1, j+1, k+1) = max; } //TRACE("%f\n", Padded(i+1, j+1, k+1)); } //form cubes float ai, aj, ak; //jmc: for speed, declare them only once for (int i=0; i<Padded.GetXSize()*Resolution-1; i++){ for (int j=0; j<Padded.GetYSize()*Resolution-1; j++){ for (int k=0; k<Padded.GetZSize()*Resolution-1; k++){ ai = i-0.5f; aj = j-0.5f; ak = k-0.5f; GridCell.p[0] = CVertex(Vec3D<>(Scale*ai, Scale*aj, Scale*ak), CColor(aR(i, j, k), aG(i, j, k), aB(i, j, k))); GridCell.val[0] = Padded(i, j, k); GridCell.p[1] = CVertex(Vec3D<>(Scale*(ai+1), Scale*aj, Scale*ak), CColor(aR(i+1, j, k), aG(i+1, j, k), aB(i+1, j, k))); GridCell.val[1] = Padded(i+1, j, k); GridCell.p[2] = CVertex(Vec3D<>(Scale*(ai+1), Scale*(aj+1), Scale*ak), CColor(aR(i+1, j+1, k), aG(i+1, j+1, k), aB(i+1, j+1, k))); GridCell.val[2] = Padded(i+1, j+1, k); GridCell.p[3] = CVertex(Vec3D<>(Scale*ai, Scale*(aj+1), Scale*ak), CColor(aR(i, j+1, k), aG(i, j+1, k), aB(i, j+1, k))); GridCell.val[3] = Padded(i, j+1, k); GridCell.p[4] = CVertex(Vec3D<>(Scale*ai, Scale*aj, Scale*(ak+1)), CColor(aR(i, j, k+1), aG(i, j, k+1), aB(i, j, k+1))); GridCell.val[4] = Padded(i, j, k+1); GridCell.p[5] = CVertex(Vec3D<>(Scale*(ai+1), Scale*aj, Scale*(ak+1)), CColor(aR(i+1, j, k+1), aG(i+1, j, k+1), aB(i+1, j, k+1))); GridCell.val[5] = Padded(i+1, j, k+1); GridCell.p[6] = CVertex(Vec3D<>(Scale*(ai+1), Scale*(aj+1), Scale*(ak+1)), CColor(aR(i+1, j+1, k+1), aG(i+1, j+1, k+1), aB(i+1, j+1, k+1))); GridCell.val[6] = Padded(i+1, j+1, k+1); GridCell.p[7] = CVertex(Vec3D<>(Scale*ai, Scale*(aj+1), Scale*(ak+1)), CColor(aR(i, j+1, k+1), aG(i, j+1, k+1), aB(i, j+1, k+1))); GridCell.val[7] = Padded(i, j+1, k+1); Polygonise(GridCell, Thresh, pMeshOut); //crunch this cube and add the vertices... } } } pMeshOut->WeldClose(Scale/2); pMeshOut->CalcFaceNormals(); pMeshOut->CalcVertNormals(); //pMeshOut->WeldClose(Scale); }