Beispiel #1
0
// Write SbPlane value to output stream. Used from SoSFPlane and
// SoMFPlane.
void
sosfplane_write_value(SoOutput * out, const SbPlane & p)
{
  out->write(p.getNormal()[0]);
  if (!out->isBinary()) out->write(' ');
  out->write(p.getNormal()[1]);
  if (!out->isBinary()) out->write(' ');
  out->write(p.getNormal()[2]);
  if (!out->isBinary()) out->write("  ");
  out->write(p.getDistanceFromOrigin());
}
Beispiel #2
0
bool
XipGeomUtils::isOnPlane(const SbVec3f& pt, const SbPlane &plane)
{
    float dist = pt.dot(plane.getNormal()) - plane.getDistanceFromOrigin();
    if ( fabs(dist)<XIP_EPSILON ) return true;

    return false;
}
Beispiel #3
0
bool
XipGeomUtils::intersect(const SbLine &line, const SbPlane &plane, SbVec3f &pt)
{
    float t, denom;

    // solve for t:
    //  n . (l.p + t * l.d) - d == 0

    denom = plane.getNormal().dot(line.getDirection());
    if ( fabs(denom) < XIP_EPSILON )
        return FALSE;

    //  t = - (n . l.p - d) / (n . l.d)
    t = - (plane.getNormal().dot(line.getPosition()) - plane.getDistanceFromOrigin()) /  denom;

    pt = line.getPosition() + t * line.getDirection();
    return TRUE;
}
Beispiel #4
0
void
SoOrthoSlice::rayPick(SoRayPickAction * action)
{
  if (!this->shouldRayPick(action)) return;

  SoState * state = action->getState();
  if (!PRIVATE(this)->confirmValidInContext(state)) { return; }

  const CvrVoxelBlockElement * vbelem = CvrVoxelBlockElement::getInstance(state);
  if (vbelem == NULL) { return; }

  this->computeObjectSpaceRay(action);
  const SbLine & ray = action->getLine();

  const SbPlane sliceplane = PRIVATE(this)->getSliceAsPlane(action);

  SbVec3f intersection;
  if (sliceplane.intersect(ray, intersection) && // returns FALSE if parallel
      action->isBetweenPlanes(intersection)) {

    SbVec3s ijk = vbelem->objectCoordsToIJK(intersection);

    const SbVec3s & voxcubedims = vbelem->getVoxelCubeDimensions();
    const SbBox3s voxcubebounds(SbVec3s(0, 0, 0), voxcubedims - SbVec3s(1, 1, 1));

    if (voxcubebounds.intersect(ijk)) {

      SoPickedPoint * pp = action->addIntersection(intersection);
      // if NULL, something else is obstructing the view to the
      // volume, the app programmer only want the nearest, and we
      // don't need to continue our intersection tests
      if (pp == NULL) return;
      pp->setObjectNormal(sliceplane.getNormal());

      SoOrthoSliceDetail * detail = new SoOrthoSliceDetail;
      pp->setDetail(detail, this);

      detail->objectcoords = intersection;
      detail->ijkcoords = ijk;
      detail->voxelvalue = vbelem->getVoxelValue(ijk);

      if (CvrUtil::useFlippedYAxis()) {
        static SbBool flag = FALSE;
        if (!flag) {
          SoDebugError::postWarning("SoOrthoSlice::rayPick", 
                                    "RayPick'ing will not be correct for SoOrthoSlice when the "
                                    "obsolete CVR_USE_FLIPPED_Y_AXIS envvar is active.");
          flag = TRUE;
        }
      }

    }
  }

  // Common clipping plane handling.
  SoOrthoSlice::doAction(action);
}
Beispiel #5
0
bool
XipGeomUtils::intersect(const SbVec3f &u, const SbVec3f &v, const SbPlane &plane, SbVec3f &pt)
{
    float d0 = u.dot(plane.getNormal()) - plane.getDistanceFromOrigin();
    float d1 = v.dot(plane.getNormal()) - plane.getDistanceFromOrigin();

    if ( d0*d1> -XIP_EPSILON ) return false;

    return XipGeomUtils::intersect(SbLine(u, v), plane, pt);
}
Beispiel #6
0
bool
XipGeomUtils::isIntersect(const SbVec3f &u, const SbVec3f &v, const SbPlane &plane)
{
    float d0 = u.dot(plane.getNormal()) - plane.getDistanceFromOrigin();
    float d1 = v.dot(plane.getNormal()) - plane.getDistanceFromOrigin();

    if ( d0*d1>XIP_EPSILON ) return false;

    return true;
}
Beispiel #7
0
/*!
  Clip polygon against \a plane. This might change the number of
  vertices in the polygon. For each time a new vertex is created, the
  callback supplied in the constructor (if != NULL) is called with the
  line being clipped and the new vertex calculated. The callback
  should return a new void pointer to be stored by the clipper.
*/
void
SbClip::clip(const SbPlane & plane)
{
  int n = this->array[this->curr].getLength();

  if (n == 0) return;

  // create loop
  SbClipData dummy = this->array[this->curr][0];
  this->array[this->curr].append(dummy);

  const SbVec3f & planeN = plane.getNormal();

  for (int i = 0; i < n; i++) {
    SbVec3f v0, v1;
    void * data0, *data1;
    this->array[this->curr][i].get(v0, data0);
    this->array[this->curr][i+1].get(v1, data1);

    float d0 = plane.getDistance(v0);
    float d1 = plane.getDistance(v1);

    if (d0 >= 0.0f && d1 < 0.0f) { // exit plane
      SbVec3f dir = v1-v0;
      // we know that v0 != v1 since we got here
      (void) dir.normalize();
      float dot = dir.dot(planeN);
      SbVec3f newvertex = v0 - dir * (d0/dot);
      void * newdata = NULL;
      if (this->callback) {
        newdata = this->callback(v0, data0, v1, data1, newvertex, this->cbdata);
      }
      outputVertex(newvertex, newdata);
    }
    else if (d0 < 0.0f && d1 >= 0.0f) { // enter plane
      SbVec3f dir = v1-v0;
      // we know that v0 != v1 since we got here
      (void) dir.normalize();
      float dot = dir.dot(planeN);
      SbVec3f newvertex = v0 - dir * (d0/dot);
      void * newdata = NULL;
      if (this->callback) {
        newdata = this->callback(v0, data0, v1, data1, newvertex, this->cbdata);
      }
      outputVertex(newvertex, newdata);
      outputVertex(v1, data1);
    }
    else if (d0 >= 0.0f && d1 >= 0.0f) { // in plane
      outputVertex(v1, data1);
    }
  }
  this->array[this->curr].truncate(0);
  this->curr ^= 1;
}
void ObjectSimpleViewer::
stateChanged(
  ClipPlaneButton::statetype state)
{
  switch(state)
  {
    case ClipPlaneButton::ClipOn:
      {
	if(!m_clipPlaneManip)
	{
	  //create at first use
	  m_clipPlaneManip = new SoClipPlaneManip;
	  m_clipPlaneManip->ref();
	  SoGetBoundingBoxAction ba(m_viewer->getViewportRegion());
	  ba.apply(blinker_root);
	  SbBox3f box = ba.getBoundingBox();
	  m_clipPlaneManip->setValue(box, SbVec3f(1.0f, 0.0f, 0.0f), 1.00f);
	}
	SbPlane plane = m_clipPlaneManip->plane.getValue();
	m_clipPlaneManip->plane.setValue(SbPlane(-plane.getNormal(),
	    -plane.getDistanceFromOrigin()));
	emit addedClipPlane(m_clipPlaneManip);  //remove ortho slices
      }
      break;
    case ClipPlaneButton::ClipOff:
      emit addedClipPlane(NULL);  //remove ortho slices
      break;
    case ClipPlaneButton::ClipOnly:
      if(!m_clipPlane)
      {
        //create at first use
	if(!m_clipPlaneManip)
	{
	  //create at first use
	  m_clipPlaneManip = new SoClipPlaneManip;
	  m_clipPlaneManip->ref();
	}
	m_clipPlane = new SoClipPlane;
	m_clipPlane->ref();
	m_clipPlane->plane.connectFrom(&(m_clipPlaneManip->plane));
      }
      emit addedClipPlane(m_clipPlane);  //remove ortho slices
      break;
  }
}
Beispiel #9
0
SbBool XipGeomUtils::planeIntersect(const SbPlane & p1, const SbPlane & p2, SbLine & line)
{
    // Based on code from Graphics Gems III, Plane-to-Plane Intersection
    // by Priamos Georgiades
    // http://www.cs.ualberta.ca/~graphics/books/GraphicsGems/gemsiii/pl2plane.c

    float invdet;  // inverse of 2x2 matrix determinant
    SbVec3f dir2;  // holds the squares of the coordinates of xdir

    SbVec3f xpt;
    SbVec3f xdir;
    xdir = p1.getNormal().cross(p2.getNormal());

    dir2[0] = xdir[0] * xdir[0];
    dir2[1] = xdir[1] * xdir[1];
    dir2[2] = xdir[2] * xdir[2];

    const SbVec3f & pl1n = p1.getNormal();
    const SbVec3f & pl2n = p2.getNormal();
    const float pl1w = - p1.getDistanceFromOrigin();
    const float pl2w = - p2.getDistanceFromOrigin();

    if ( (dir2[2] > dir2[1]) && (dir2[2] > dir2[0]) && (dir2[2] > XIP_FLT_EPSILON) )
    {
        // then get a point on the XY plane
        invdet = 1.0f / xdir[2];
        xpt = SbVec3f(
                  pl1n[1] * pl2w - pl2n[1] * pl1w,
                  pl2n[0] * pl1w - pl1n[0] * pl2w,
                  0.0f);
    }
    else if ( (dir2[1] > dir2[0]) && (dir2[1] > XIP_FLT_EPSILON) )
    {
        // then get a point on the XZ plane
        invdet = -1.0f / xdir[1];
        xpt = SbVec3f(
                  pl1n[2] * pl2w - pl2n[2] * pl1w,
                  0.0f,
                  pl2n[0] * pl1w - pl1n[0] * pl2w);
    }
    else if (dir2[0] > XIP_FLT_EPSILON)
    {
        // then get a point on the YZ plane
        invdet = 1.0f / xdir[0];
        xpt = SbVec3f(
                  0.0f,
                  pl1n[2] * pl2w - pl2n[2] * pl1w,
                  pl2n[1] * pl1w - pl1n[1] * pl2w);
    }
    else
    {
        // xdir is zero, then no point of intersection exists
        return FALSE;
    }

    xpt *= invdet;
    invdet = 1.0f / (float) sqrt(dir2[0] + dir2[1] + dir2[2]);

    xdir *= invdet;
    line = SbLine(xpt, xpt+xdir);

    return TRUE;
}
void SoXipMprIntersectionPlanes::GLRender(SoGLRenderAction * action)
{
	if (!mIntersectionPlane || !mColor) return;
	if (!on.getValue()) return;

	// check state
	SoState *state = action->getState();
	if (!state) return;

	SoXipMprPlaneElement *element = SoXipMprPlaneElement::getInstance(state);
	if (!element) return;

	int numPlanes = element->getNum();
	if (numPlanes <= 0) return;

	GLboolean lightEnabled = glIsEnabled(GL_LIGHTING);
	glDisable(GL_LIGHTING);

	mIntersectionPlane->boundingBox.setValue(viewBoundingBox.getValue());

	SbPlane plane;
	SbColor color;
	for (int i = 0; i < numPlanes; i++)
	{
		plane = XipGeomUtils::planeFromMatrix(element->getMatrix(i));
		color = element->getColor(i);

		if (i > 0)
		{
			SbPlane newPlane = mIntersectionPlane->plane.getValue();
			if ((newPlane.getNormal() - plane.getNormal()).length() < 0.001)
			{
				if (fabs(newPlane.getDistanceFromOrigin() - plane.getDistanceFromOrigin()) <= 0.001)
				{
					continue;
				}
			}
		}

		mIntersectionPlane->plane.setValue(plane);

		if ((parts.getValue() == BACK) || (parts.getValue() == ALL))
		{
			mColor->rgb.setValue(color * 0.6f);
			mIntersectionPlane->parts.setValue(SoXipIntersectionPlane::BACK);
			
			action->traverse(mSeparator);
		}

		if ((parts.getValue() == FRONT) || (parts.getValue() == ALL))
		{
			mColor->rgb.setValue(color);
			mIntersectionPlane->parts.setValue(SoXipIntersectionPlane::FRONT);

			action->traverse(mSeparator);
		}
	}

	if (lightEnabled)
		glEnable(GL_LIGHTING);
}
bool ObjectSimpleViewer::
saveAsXml(
  QXmlStreamWriter *xmlWriter)
{
  Q_ASSERT(xmlWriter);
  xmlWriter->writeTextElement("Title", windowTitle());
  if(m_mixSlider)
  {
    xmlWriter->writeTextElement("Mix",
	QString("%1").arg(m_mixSlider->value()));
  }
  xmlWriter->writeStartElement("Geometry");
  const QRect geom = parentWidget()->geometry();
  xmlWriter->writeTextElement("X", QString("%1").arg(geom .x()));
  xmlWriter->writeTextElement("Y", QString("%1").arg(geom .y()));
  xmlWriter->writeTextElement("Width", QString("%1").arg(geom .width()));
  xmlWriter->writeTextElement("Height", QString("%1").arg(geom .height()));
  xmlWriter->writeEndElement();

  if(m_clipPlaneManip)
  {
    xmlWriter->writeStartElement("ClipPlane");

    SbPlane plane = m_clipPlaneManip->plane.getValue();
    SbVec3f vec = plane.getNormal();
    xmlWriter->writeStartElement("Normal");
    xmlWriter->writeTextElement("X", QString("%1").arg(vec[0]));
    xmlWriter->writeTextElement("Y", QString("%1").arg(vec[1]));
    xmlWriter->writeTextElement("Z", QString("%1").arg(vec[2]));
    xmlWriter->writeEndElement();

    xmlWriter->writeTextElement("Distance",
        QString("%1").arg(plane.getDistanceFromOrigin()));

    vec = m_clipPlaneManip->draggerPosition.getValue();
    xmlWriter->writeStartElement("Position");
    xmlWriter->writeTextElement("X", QString("%1").arg(vec[0]));
    xmlWriter->writeTextElement("Y", QString("%1").arg(vec[1]));
    xmlWriter->writeTextElement("Z", QString("%1").arg(vec[2]));
    xmlWriter->writeEndElement();
    SoDragger *dragger = m_clipPlaneManip->getDragger();
    if(dragger && dragger->isOfType(SoJackDragger::getClassTypeId()))
    {
      SoJackDragger *jd = (SoJackDragger*)dragger;
      vec = jd->scaleFactor.getValue();
      xmlWriter->writeStartElement("Scalefactor");
      xmlWriter->writeTextElement("X", QString("%1").arg(vec[0]));
      xmlWriter->writeTextElement("Y", QString("%1").arg(vec[1]));
      xmlWriter->writeTextElement("Z", QString("%1").arg(vec[2]));
      xmlWriter->writeEndElement();
    }
    xmlWriter->writeTextElement("Distance",
        QString("%1").arg(plane.getDistanceFromOrigin()));

    xmlWriter->writeEndElement();
  }

  for(int i = 0; i < views.size(); ++i)
  {
    views.at(i)->saveAsXml(xmlWriter);
  }
  return(true);
}