SbBool SoXipPolygon::isConsistent() const { // check if the contour size is greater than the minimum size. const SbVec3f* pointPtr = point.getValues(0); SbBox3f bbox; for( int i = 0; i < point.getNum(); ++ i ) bbox.extendBy( pointPtr[i] ); SbVec3f bbSize; bbox.getSize(bbSize[0], bbSize[1], bbSize[2]); float screenScale = mViewVolume.getHeight() / mViewport.getViewportSizePixels()[1]; float bbLengthPix = bbSize.length() / screenScale; return ( bbLengthPix >= (2 * CLOSING_MIN_PIXEL_DISTANCE) ); }
void SoSurroundScale::updateMySurroundParams(SoAction *action, const SbMatrix &myInv ) // //////////////////////////////////////////////////////////////////////// { const SoFullPath *curPath = (const SoFullPath *) action->getCurPath(); int curPathLength = curPath->getLength(); // If the container node is out of range, just return. int numUpCon = (int) numNodesUpToContainer.getValue(); if ( (numUpCon <= 0) || (numUpCon > (curPathLength - 1)) ){ cachedScale.setValue(1,1,1); cachedInvScale.setValue(1,1,1); cachedTranslation.setValue(0,0,0); cacheOK = FALSE; return; } // CHECK TO SEE IF OUR CACHED VALUES ARE OKAY // IF SO, JUST RETURN if ( cacheOK ) return; // Find the path to apply the bounding box action to. It should end // 'numUpCon' above this one. SoPath *applyPath = curPath->copy(0, (curPathLength - numUpCon)); applyPath->ref(); // See if there is a node to do a reset at. If so, build a resetPath SoPath *resetPath = NULL; int numUpReset = (int) numNodesUpToReset.getValue(); if (numUpReset >= 0 && (numUpReset < numUpCon) ) { // Build a path ending at the reset node. resetPath = curPath->copy(0, curPathLength - numUpReset ); resetPath->ref(); } SoFullPath *fullResetPath = (SoFullPath *) resetPath; // Create a getBoundingBox action // Set the reset path if we have one. // Apply the bounding box action and find out how big the box was. // Temporarily set the ignoreInBbox flag TRUE, so we don't infinite loop! SbViewportRegion vpRegion(0,0); SoState *state = action->getState(); vpRegion = SoViewportRegionElement::get(state); static SoGetBoundingBoxAction *boundingBoxAction = NULL; if (boundingBoxAction == NULL) boundingBoxAction = new SoGetBoundingBoxAction(vpRegion); else boundingBoxAction->setViewportRegion(vpRegion); if (fullResetPath) boundingBoxAction->setResetPath( fullResetPath, FALSE, SoGetBoundingBoxAction::BBOX); SbBool oldFlag = isIgnoreInBbox(); setIgnoreInBbox( TRUE ); boundingBoxAction->apply( applyPath ); setIgnoreInBbox( oldFlag ); SbXfBox3f &myXfBox = boundingBoxAction->getXfBoundingBox(); // Transform the box into our local space, then project it. myXfBox.transform( myInv ); SbBox3f myBox = myXfBox.project(); // Get the scale for this node to add to the ctm. if (myBox.isEmpty()) { cachedScale.setValue(1,1,1); cachedInvScale.setValue(1,1,1); cachedTranslation.setValue(0,0,0); cacheOK = TRUE; return; } else { float x, y, z; myBox.getSize(x,y,z); cachedScale.setValue( .5*x, .5*y, .5*z ); float minLength = .01 * cachedScale.length(); // Macro defined just before beginning of this method. FUDGE(cachedScale[0],minLength); FUDGE(cachedScale[1],minLength); FUDGE(cachedScale[2],minLength); // Find the inverse values for (int j = 0; j < 3; j++ ) cachedInvScale[j] = 1.0 / cachedScale[j]; } // Get the translation for this node to add to the ctm. // This will get the cube centered about the bbox center. // If the bounding box is not centered at the origin, we have to // move the cube to the correct place. if (doTranslations) cachedTranslation = 0.5 * ( myBox.getMin() + myBox.getMax() ); else cachedTranslation.setValue(0,0,0); // Establish the cached values to save us some time later... cacheOK = TRUE; if (resetPath) resetPath->unref(); if (applyPath) applyPath->unref(); }