HitInfo GeometryNode::intersects(Point3D origin, Vector3D dir) const { origin = get_inverse() * origin; dir = get_inverse() * dir; HitInfo info = m_primitive->intersects(origin, dir); for (unsigned int i = 0; i < info.hits.size(); i++) { info.hits.at(i) = m_material->apply_normal_map(info.hits.at(i)); info.hits.at(i) = m_material->apply_bump_map(info.hits.at(i)); info.hits.at(i).material = m_material; info.hits.at(i).intersection = get_transform() * info.hits.at(i).intersection; info.hits.at(i).normal = get_inverse().transpose() * info.hits.at(i).normal; } for (unsigned int i = 0; i < info.lines.size(); i++) { info.lines.at(i).first = m_material->apply_normal_map(info.lines.at(i).first); info.lines.at(i).second = m_material->apply_normal_map(info.lines.at(i).second); info.lines.at(i).first = m_material->apply_bump_map(info.lines.at(i).first); info.lines.at(i).second = m_material->apply_bump_map(info.lines.at(i).second); info.lines.at(i).first.material = m_material; info.lines.at(i).second.material = m_material; info.lines.at(i).first.intersection = get_transform() * info.lines.at(i).first.intersection; info.lines.at(i).second.intersection = get_transform() * info.lines.at(i).second.intersection; info.lines.at(i).first.normal = get_inverse().transpose() * info.lines.at(i).first.normal; info.lines.at(i).second.normal = get_inverse().transpose() * info.lines.at(i).second.normal; } return info; }
bool join (patch& p1, patch p2, tree t) { //cout << "Join " << p1 << LF << "with " << p2 << LF; if (get_type (p1) == PATCH_AUTHOR && get_type (p2) == PATCH_AUTHOR && get_author (p1) == get_author (p2)) { double author= get_author (p1); patch q1= p1[0]; patch q2= p2[0]; bool r= join (q1, q2, t); if (r) p1= patch (author, q1); return r; } if (get_type (p1) == PATCH_MODIFICATION && get_type (p2) == PATCH_MODIFICATION) { modification m1= get_modification (p1); modification m2= get_modification (p2); modification i2= get_inverse (p2); modification i1= get_inverse (p1); bool r= join (m1, m2, t); bool v= join (i2, i1, clean_apply (p2, clean_apply (p1, t))); if (r && v) p1= patch (m1, i2); return r && v; } if (get_type (p1) == PATCH_COMPOUND && nr_children (p1) > 0 && nr_children (remove_set_cursor (p1)) == 1 && nr_children (p1[0]) == 1) { patch q= p1[0]; bool rf= join (q, p2, t); if (rf) p1= q; return rf; } if (get_type (p2) == PATCH_COMPOUND && nr_children (p2) > 0 && nr_children (remove_set_cursor (p2)) == 1 && nr_children (p2[0]) == 1) { patch q= p2[0]; bool rf= join (p1, q, t); if (rf) { array<patch> a= children (p1); array<patch> b= children (p2); p1= patch (append (a, range (b, 1, N(b)))); } return rf; } return false; }
patch invert (patch p, tree t) { switch (get_type (p)) { case PATCH_MODIFICATION: return patch (get_inverse (p), get_modification (p)); case PATCH_BRANCH: ASSERT (N(p) <= 1, "ambiguous application"); case PATCH_COMPOUND: { int i, n=N(p); array<patch> r(n); for (i=0; i<n; i++) { r[n-1-i]= invert (p[i], t); t= clean_apply (p[i], t); } return patch (get_type (p) == PATCH_BRANCH, r); } case PATCH_BIRTH: return patch (get_author (p), !get_birth (p)); case PATCH_AUTHOR: return patch (get_author (p), invert (p[0], t)); default: FAILED ("unsupported patch type"); return patch (); } }
void insert (array<patch>& a, patch p) { if (get_type (p) == PATCH_COMPOUND) { int i, n= N(p); for (i=0; i<n; i++) insert (a, p[i]); } else if (get_type (p) == PATCH_MODIFICATION && N(a) > 0 && get_type (a[N(a)-1]) == PATCH_MODIFICATION && (get_inverse (a[N(a)-1]) == get_modification (p) && get_modification (a[N(a)-1]) == get_inverse (p))) { // cout << "Cancel " << a[N(a)-1] << " against " << p << "\n"; a->resize (N(a) - 1); } else a << p; }
bool operator == (patch p1, patch p2) { if (get_type (p1) != get_type (p2)) return false; switch (get_type (p1)) { case PATCH_MODIFICATION: return get_modification (p1) == get_modification (p2) && get_inverse (p1) == get_inverse (p2); case PATCH_COMPOUND: case PATCH_BRANCH: if (N(p1) != N(p2)) return false; for (int i=0; i<N(p1); i++) if (p1[i] != p2[i]) return false; return true; case PATCH_BIRTH: return get_birth (p1) == get_birth (p2) && get_author (p1) == get_author (p2); case PATCH_AUTHOR: return get_author (p1) == get_author (p2) && p1[0] == p2[0]; default: FAILED ("unsupported patch type"); } return false; }
HitInfo SceneNode::intersects(Point3D origin, Vector3D dir) const { HitInfo info; origin = get_inverse() * origin; dir = get_inverse() * dir; for (ChildList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) { HitInfo h = (*it)->intersects(origin, dir); for (unsigned int i = 0; i < h.hits.size(); i++) { h.hits.at(i).intersection = get_transform() * h.hits.at(i).intersection; h.hits.at(i).normal = get_inverse().transpose() * h.hits.at(i).normal; } for (unsigned int i = 0; i < h.lines.size(); i++) { h.lines.at(i).first.intersection = get_transform() * h.lines.at(i).first.intersection; h.lines.at(i).second.intersection = get_transform() * h.lines.at(i).second.intersection; h.lines.at(i).first.normal = get_inverse().transpose() * h.lines.at(i).first.normal; h.lines.at(i).second.normal = get_inverse().transpose() * h.lines.at(i).second.normal; } info = HitInfo::merge_info(info, h); } return info; }
patch copy (patch p) { switch (get_type (p)) { case PATCH_MODIFICATION: return patch (copy (get_modification (p)), copy (get_inverse (p))); case PATCH_COMPOUND: case PATCH_BRANCH: { int i, n= N(p); array<patch> r (n); for (i=0; i<N(p); i++) r[i]= copy (p[i]); return patch (get_type (p) == PATCH_BRANCH, r); } case PATCH_BIRTH: return p; case PATCH_AUTHOR: return patch (get_author (p), copy (p[0])); default: FAILED ("unsupported patch type"); } return p; }
tm_ostream& operator << (tm_ostream& out, patch p) { switch (get_type (p)) { case PATCH_MODIFICATION: out << get_modification (p) << " -- " << get_inverse (p); break; case PATCH_COMPOUND: if (N(p) == 0) out << "No children"; else { out << "Composite" << INDENT; for (int i=0; i<N(p); i++) out << LF << p[i]; out << UNINDENT; } break; case PATCH_BRANCH: if (N(p) == 0) out << "No branches"; else for (int i=0; i<N(p); i++) { if (i != 0) out << LF; out << "Branch " << i << INDENT << LF << p[i] << UNINDENT; } break; case PATCH_BIRTH: if (get_birth (p)) out << "Birth "; else out << "Death "; out << get_author (p); break; case PATCH_AUTHOR: out << "Author " << get_author (p) << INDENT << LF; out << p[0]; out << UNINDENT; break; default: FAILED ("unsupported patch type"); } return out; }
struct map_type *dfp( function func, struct map_type *map_x, __float128 grad_toler, __float128 fx_toler, const unsigned int max_iter ) { unsigned int iter; __float128 lambda, result_func_value, temp_func_value; struct map_type *result, *b, *grad1, *tmp, *s, *grad2, *g, *tmp2, *tmp3, *d, *x1, *x2, *x3, *x4, *x5; result = NULL; result_func_value = func( map_x ); b = get_identity_matrix( map_x->j_size ); grad1 = first_derivatives( func, map_x ); tmp = transposition( grad1 ); deallocate( grad1 ); grad1 = tmp; for( iter = 0 ; iter < max_iter; iter++ ) { tmp = multiplicate_on_value( -1, b ); s = multiplicate( tmp, grad1 ); deallocate( tmp ); tmp = transposition( s ); tmp2 = multiplicate_on_value( powf( get_euclidean_distance( s ), -1 ), tmp ); deallocate( s ); deallocate( tmp ); s = tmp2; lambda = 1; lambda = line_search( func, map_x, lambda, s ); d = multiplicate_on_value( lambda, s ); tmp = addition( map_x, d ); deallocate( d ); deallocate( map_x ); map_x = tmp; temp_func_value = func( map_x ); if( result_func_value > temp_func_value ) { iter = 0; result_func_value = temp_func_value; if( result != NULL ) { deallocate( result ); } result = clone( map_x ); } grad2 = first_derivatives( func, map_x ); tmp = transposition( grad2 ); deallocate( grad2 ); grad2 = tmp; g = subtraction( grad2, grad1 ); deallocate( grad1 ); grad1 = grad2; if( get_euclidean_distance( grad1 ) < grad_toler ) { /// TODO: Нужно очистить память break; } tmp = transposition( s ); x1 = multiplicate( s, tmp ); x2 = multiplicate( s, g ); deallocate( s ); deallocate( tmp ); tmp = multiplicate_on_value( lambda, x1 ); tmp2 = get_inverse( x2 ); tmp3 = multiplicate( tmp, tmp2 ); deallocate( tmp ); tmp = addition( b, tmp3 ); deallocate( x1 ); deallocate( x2 ); deallocate( tmp2 ); deallocate( tmp3 ); deallocate( b ); b = tmp; x3 = multiplicate( b, g ); tmp = transposition( b ); x4 = multiplicate( tmp, g ); deallocate( tmp ); tmp = transposition( g ); tmp2 = multiplicate( tmp, b ); x5 = multiplicate( tmp2, g ); deallocate( g ); deallocate( tmp ); deallocate( tmp2 ); tmp = transposition( x4 ); tmp2 = multiplicate( x3, tmp ); deallocate( tmp ); tmp = get_inverse( x5 ); tmp3 = multiplicate( tmp, tmp2 ); deallocate( tmp ); tmp = subtraction( b, tmp3 ); deallocate( b ); b = tmp; deallocate( tmp2 ); deallocate( tmp3 ); deallocate( x3 ); deallocate( x4 ); deallocate( x5 ); } return result; }
friend typename boost::graph_traits<GraphCodom>::vertex_descriptor get(const InvertedVertexMap &m, const GraphDom &gDom, const GraphCodom &gCodom, typename boost::graph_traits<GraphDom>::vertex_descriptor v) { return get_inverse(m.m, gCodom, gDom, v); }
bool swap (patch& p1, patch& p2, double a1, double a2) { if (is_nil (p1) || is_nil (p2)) return false; if (get_type (p1) == PATCH_BRANCH) return false; if (get_type (p2) == PATCH_BRANCH) return false; if (get_type (p1) == PATCH_COMPOUND) { int n= N(p1); array<patch> a (n); for (int i=0; i<n; i++) a[i]= p1[i]; for (int i=n-1; i>=0; i--) { if (!swap (a[i], p2, a1, a2)) return false; swap_basic (a[i], p2); } p1= p2; p2= patch (a); return true; } if (get_type (p2) == PATCH_COMPOUND) { int n= N(p2); array<patch> a (n); for (int i=0; i<n; i++) a[i]= p2[i]; for (int i=0; i<n; i++) { if (!swap (p1, a[i], a1, a2)) return false; swap_basic (p1, a[i]); } p2= p1; p1= patch (a); return true; } if (get_type (p1) == PATCH_AUTHOR) { patch s= p1[0]; bool r= swap (s, p2, get_author (p1), a2); p2= patch (get_author (p1), p2); p1= s; return r; } if (get_type (p2) == PATCH_AUTHOR) { patch s= p2[0]; bool r= swap (p1, s, a1, get_author (p2)); p1= patch (get_author (p2), p1); p2= s; return r; } if (get_type (p1) == PATCH_BIRTH) { if (get_author (p1) == a2) return false; return swap_basic (p1, p2); } if (get_type (p2) == PATCH_BIRTH) { if (get_author (p2) == a1) return false; return swap_basic (p1, p2); } if (get_type (p1) == PATCH_MODIFICATION && get_type (p2) == PATCH_MODIFICATION) { modification m1= get_modification (p1); modification m2= get_modification (p2); modification i1= get_inverse (p1); modification i2= get_inverse (p2); bool r= swap (m1, m2); bool v= swap (i2, i1); p1= patch (m1, i1); p2= patch (m2, i2); return r && v && possible_inverse (m1, i1) && possible_inverse (m2, i2); } FAILED ("invalid situation"); return false; }
HitInfo CSGNode::intersects(Point3D origin, Vector3D dir) const { HitInfo info; origin = get_inverse() * origin; dir = get_inverse() * dir; bool first = true; for (ChildList::const_iterator it = m_children.begin(); it != m_children.end(); ++it) { HitInfo h = (*it)->intersects(origin, dir); for (unsigned int i = 0; i < h.hits.size(); i++) { h.hits.at(i).intersection = get_transform() * h.hits.at(i).intersection; h.hits.at(i).normal = get_inverse().transpose() * h.hits.at(i).normal; } for (unsigned int i = 0; i < h.lines.size(); i++) { h.lines.at(i).first.intersection = get_transform() * h.lines.at(i).first.intersection; h.lines.at(i).second.intersection = get_transform() * h.lines.at(i).second.intersection; h.lines.at(i).first.normal = get_inverse().transpose() * h.lines.at(i).first.normal; h.lines.at(i).second.normal = get_inverse().transpose() * h.lines.at(i).second.normal; } switch(m_type) { case UNION: { info = HitInfo::merge_info(info, h); break; } case INTERSECTION: { if (first) { info = h; } else if (h.empty()) { info.clear(); return info; } else { std::vector<HitInfo::LineSegment> lines; for (unsigned int i = 0; i < info.lines.size(); i++) { HitInfo::LineSegment line = info.lines.at(i); for (unsigned int j = 0; j < h.lines.size(); j++) { HitInfo::LineSegment sub = h.lines.at(j); if (line.first.t >= sub.first.t && line.second.t <= sub.second.t) { // subtracting line contains the first line lines = HitInfo::insert_line_in_order(lines, line); } else if (line.first.t < sub.first.t && line.second.t > sub.second.t) { // first line contains subtracting line lines = HitInfo::insert_line_in_order(lines, sub); } else if (line.first.t > sub.first.t && line.first.t < sub.second.t && line.second.t > sub.second.t) { // tail end of line overlaps with subtracting line. double len = (sub.second.intersection-line.first.intersection).length(); if (len > EPSILON) { lines = HitInfo::insert_line_in_order(lines, std::make_pair(line.first, sub.second)); } } else if (line.first.t < sub.first.t && line.second.t > sub.first.t && line.second.t < sub.second.t) { // head end of line overlaps with subtracting line double len = (line.second.intersection-sub.first.intersection).length(); if (len > EPSILON) { lines = HitInfo::insert_line_in_order(lines, std::make_pair(sub.first, line.second)); } } else { // no overlap, do nothing continue; } } } info.lines = lines; std::vector<Hit> hits; for (unsigned i = 0; i < info.hits.size(); i++) { Hit hit = info.hits.at(i); for (unsigned j = 0; j < h.lines.size(); j++) { HitInfo::LineSegment sub = h.lines.at(j); if (hit.t > sub.first.t && hit.t < sub.second.t) { hits.push_back(hit); break; } } } info.hits = hits; } break; } case DIFFERENCE: { if (first && h.empty()) { return info; } else if (first && !h.empty()) { info = HitInfo::merge_info(info, h); } else if (!h.empty()) { std::vector<HitInfo::LineSegment> lines; for (unsigned int i = 0; i < info.lines.size(); i++) { HitInfo::LineSegment line = info.lines.at(i); for (unsigned int j = 0; j < h.lines.size(); j++) { HitInfo::LineSegment sub = h.lines.at(j); if (line.first.t >= sub.first.t && line.second.t <= sub.second.t) { // subtracting line contains the first line continue; } else if (line.first.t < sub.first.t && line.second.t > sub.second.t) { // first line contains subtracting line; divide into two lines. sub.first.normal = -sub.first.normal; sub.second.normal = -sub.second.normal; double len1 = (sub.first.intersection - line.first.intersection).length(); double len2 = (line.second.intersection- sub.second.intersection).length(); if (len1 > EPSILON) { lines = HitInfo::insert_line_in_order(lines, std::make_pair(line.first, sub.first)); } if (len2 > EPSILON) { lines = HitInfo::insert_line_in_order(lines, std::make_pair(sub.second, line.second)); } } else if (line.first.t > sub.first.t && line.first.t < sub.second.t && line.second.t > sub.second.t) { // head end of line overlaps with subtracting line. sub.second.normal = -sub.second.normal; double len = (line.second.intersection-sub.second.intersection).length(); if (len > EPSILON) { lines = HitInfo::insert_line_in_order(lines, std::make_pair(sub.second, line.second)); } } else if (line.first.t < sub.first.t && line.second.t > sub.first.t && line.second.t < sub.second.t) { // tail end of line overlaps with subtracting line sub.first.normal = -sub.first.normal; double len = (line.first.intersection- sub.first.intersection).length(); if (len > EPSILON) { lines = HitInfo::insert_line_in_order(lines, std::make_pair(line.first, sub.first)); } } else { // no overlap, line remains unchanged. lines = HitInfo::insert_line_in_order(lines, line); } } } info.lines = lines; std::vector<Hit> hits; for (unsigned i = 0; i < info.hits.size(); i++) { Hit hit = info.hits.at(i); bool insert = true; for (unsigned j = 0; j < h.lines.size(); j++) { HitInfo::LineSegment sub = h.lines.at(j); if (hit.t > sub.first.t && hit.t < sub.second.t) { insert = false; } } if (insert) { hits.push_back(hit); } } info.hits = hits; } break; } } first = false; } return info; }