Beispiel #1
0
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;
} 
Beispiel #2
0
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;
}
Beispiel #3
0
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 ();
  }
}
Beispiel #4
0
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;
}
Beispiel #5
0
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;
}
Beispiel #6
0
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;
}
Beispiel #7
0
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;
}
Beispiel #8
0
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;
}
Beispiel #9
0
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;
}
Beispiel #10
0
	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);
	}
Beispiel #11
0
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;
}
Beispiel #12
0
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;
}