void CmdPartDesignBody::activated(int iMsg) { Q_UNUSED(iMsg); if ( !PartDesignGui::assureModernWorkflow( getDocument() ) ) return; App::Part *actPart = PartDesignGui::getActivePart (); App::Part* partOfBaseFeature = nullptr; std::vector<App::DocumentObject*> features = getSelection().getObjectsOfType(Part::Feature::getClassTypeId()); App::DocumentObject* baseFeature = nullptr; bool viewAll = features.empty(); if (!features.empty()) { if (features.size() == 1) { baseFeature = features[0]; if ( baseFeature->isDerivedFrom ( PartDesign::Feature::getClassTypeId() ) && PartDesign::Body::findBodyOf ( baseFeature ) ) { // Prevent creating bodies based on features already belonging to other bodies QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("Body can't be based on a PartDesign feature.")); baseFeature = nullptr; } else if (PartDesign::Body::findBodyOf ( baseFeature )){ QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("%1 already belongs to a body, can't use it as base feature for another body.") .arg(QString::fromUtf8(baseFeature->Label.getValue()))); baseFeature = nullptr; } else if ( baseFeature->isDerivedFrom ( Part::BodyBase::getClassTypeId() ) ) { // Prevent creating bodies based on bodies QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("Body can't be based on another body.")); baseFeature = nullptr; } else { partOfBaseFeature = App::Part::getPartOfObject(baseFeature); if (partOfBaseFeature != 0 && partOfBaseFeature != actPart){ //prevent cross-part mess QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("Base feature (%1) belongs to other part.") .arg(QString::fromUtf8(baseFeature->Label.getValue()))); baseFeature = nullptr; }; } } else { QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Bad base feature"), QObject::tr("Body may be based on no more than one feature.")); return; } } openCommand("Add a Body"); std::string bodyName = getUniqueObjectName("Body"); // add the Body feature itself, and make it active doCommand(Doc,"App.activeDocument().addObject('PartDesign::Body','%s')", bodyName.c_str()); if (baseFeature) { if (partOfBaseFeature){ //withdraw base feature from Part, otherwise visibility mandess results doCommand(Doc,"App.activeDocument().%s.removeObject(App.activeDocument().%s)", partOfBaseFeature->getNameInDocument(), baseFeature->getNameInDocument()); } doCommand(Doc,"App.activeDocument().%s.BaseFeature = App.activeDocument().%s", bodyName.c_str(), baseFeature->getNameInDocument()); } addModule(Gui,"PartDesignGui"); // import the Gui module only once a session doCommand(Gui::Command::Gui, "Gui.activeView().setActiveObject('%s', App.activeDocument().%s)", PDBODYKEY, bodyName.c_str()); // Make the "Create sketch" prompt appear in the task panel doCommand(Gui,"Gui.Selection.clearSelection()"); doCommand(Gui,"Gui.Selection.addSelection(App.ActiveDocument.%s)", bodyName.c_str()); if (actPart) { doCommand(Doc,"App.activeDocument().%s.addObject(App.ActiveDocument.%s)", actPart->getNameInDocument(), bodyName.c_str()); } // The method 'SoCamera::viewBoundingBox' is still declared as protected in Coin3d versions // older than 4.0. #if COIN_MAJOR_VERSION >= 4 // if no part feature was there then auto-adjust the camera if (viewAll) { Gui::Document* doc = Gui::Application::Instance->getDocument(getDocument()); Gui::View3DInventor* view = doc ? qobject_cast<Gui::View3DInventor*>(doc->getActiveView()) : nullptr; if (view) { SoCamera* camera = view->getViewer()->getCamera(); SbViewportRegion vpregion = view->getViewer()->getViewportRegion(); float aspectratio = vpregion.getViewportAspectRatio(); float size = Gui::ViewProviderOrigin::defaultSize(); SbBox3f bbox; bbox.setBounds(-size,-size,-size,size,size,size); camera->viewBoundingBox(bbox, aspectratio, 1.0f); } } #endif updateActive(); }
void SmTextureText2::renderString(const SmTextureFontBundle & bundle, const SbString * s, const int numstring, const SbVec3f & pos, const SbViewVolume & vv, const SbViewportRegion & vp, const SbMatrix & projmatrix, const SbMatrix & modelmatrix, const SbMatrix & invmodelmatrix, const float rotation) { // get distance from pos to camera plane SbVec3f tmp; modelmatrix.multVecMatrix(pos, tmp); float dist = -vv.getPlane(0.0f).getDistance(tmp); if (dist <= vv.getNearDist()) return; if (dist > (vv.getNearDist() + vv.getDepth())) return; float maxr = this->maxRange.getValue(); if (maxr > 0.0f && dist > maxr) return; int i; SbVec2s vpsize = vp.getViewportSizePixels(); SbVec3f screenpoint; projmatrix.multVecMatrix(pos, screenpoint); int xmin = 0; int ymax = bundle.getAscent(); int ymin = ymax - numstring * (bundle.height() + bundle.getLeading()); ymin += bundle.getLeading(); short h = ymax - ymin; short halfh = h / 2; switch (this->verticalJustification.getValue()) { case SmTextureText2::BOTTOM: break; case SmTextureText2::TOP: ymin -= bundle.getAscent(); ymax -= bundle.getAscent(); break; case SmTextureText2::VCENTER: ymin -= halfh; ymax -= halfh; break; default: assert(0 && "unknown alignment"); break; } SbList <int> widthlist; for (i = 0; i < numstring; i++) { widthlist.append(bundle.stringWidth(s[i])); } for (i = 0; i < numstring; i++) { int len = s[i].getLength(); if (len == 0) continue; SbVec2s sp; if (!get_screenpoint_pixels(screenpoint, vpsize, sp)) continue; SbVec2s n0 = SbVec2s(sp[0] + xmin, sp[1] + ymax - (i+1)*bundle.height()); short w = static_cast<short>(widthlist[i]); short halfw = w / 2; switch (this->justification.getValue()) { case SmTextureText2::LEFT: break; case SmTextureText2::RIGHT: n0[0] -= w; break; case SmTextureText2::CENTER: n0[0] -= halfw; break; default: assert(0 && "unknown alignment"); break; } if (rotation != 0) { float x = static_cast<float>(sp[0]); float y = static_cast<float>(sp[1]); glPushMatrix(); glTranslatef(x, y, 0); glRotatef(rotation * static_cast<float>(180 / M_PI), 0, 0, 1); glTranslatef(-x, -y, 0); } bundle.begin(); bundle.renderString(s[i], SbVec3f(n0[0], n0[1], screenpoint[2])); bundle.end(); if (rotation != 0) glPopMatrix(); } }
void SoXipViewportBorder::GLRender(SoGLRenderAction * action) { SbViewportRegion viewportRegion = SoViewportRegionElement::get( action->getState() ); SbVec2s s = viewportRegion.getViewportSizePixels(); double oldLineWidth = 1.0; glGetDoublev(GL_LINE_WIDTH, &oldLineWidth); glPushAttrib(GL_TRANSFORM_BIT | GL_ENABLE_BIT | GL_LINE_BIT | GL_CURRENT_BIT); glDisable(GL_LIGHTING); glDisable(GL_DEPTH_TEST); glDisable(GL_ALPHA_TEST); #if 0 // disable clip planes int maxClipPlanes; glGetIntegerv(GL_MAX_CLIP_PLANES, &maxClipPlanes); maxClipPlanes = std::min(maxClipPlanes, 16); for (int i = 0; i < maxClipPlanes; i++) { glDisable(GL_CLIP_PLANE0 + i); } #endif unsigned short pattern; float lineWidth; SbColor color; if (SoXipActiveViewportElement::get(action->getState())) { pattern = activeLinePattern.getValue(); lineWidth = activeLineWidth.getValue(); color = activeColor.getValue(); } else { pattern = inactiveLinePattern.getValue(); lineWidth = inactiveLineWidth.getValue(); color = inactiveColor.getValue(); } if (lineWidth <= 0) return; glColor3f(color[0], color[1], color[2]); glLineStipple(1, pattern); glEnable(GL_LINE_STIPPLE); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glOrtho(0, s[0], 0, s[1], -1, 1); // cast to int to avoid compiler warnings int iLineWidth = static_cast<int>(lineWidth); int iLineWidth05 = static_cast<int>(lineWidth+0.5f); if (pattern == 0xffff) { // draw solid blocks // Note that on some graphics card GL_LINE_LOOP does not look good for thicker lines // (first/last corner not filled). This is why we use GL_QUADS instead. glBegin(GL_QUADS); glVertex2i(0, 0); glVertex2i(iLineWidth, 0); glVertex2i(iLineWidth, s[1]); glVertex2i(0, s[1]); glVertex2i(0, 0); glVertex2i(s[0], 0); glVertex2i(s[0], iLineWidth); glVertex2i(0, iLineWidth); glVertex2i(s[0] - iLineWidth, 0); glVertex2i(s[0], 0); glVertex2i(s[0], s[1]); glVertex2i(s[0] - iLineWidth, s[1]); glVertex2i(0, s[1] - iLineWidth); glVertex2i(s[0], s[1] - iLineWidth); glVertex2i(s[0], s[1]); glVertex2i(0, s[1]); glEnd(); } else { // draw stippled line glLineWidth(lineWidth); lineWidth /= 2.f; glBegin(GL_LINES); glVertex2i(iLineWidth, 0 + iLineWidth); glVertex2i(s[0] - iLineWidth + 1, 0 + iLineWidth); glVertex2i(iLineWidth, s[1] - iLineWidth); glVertex2i(s[0] - iLineWidth + 1, s[1] - iLineWidth); glVertex2i(s[0] - iLineWidth05, s[1] - iLineWidth); glVertex2i(s[0] - iLineWidth05, iLineWidth); glVertex2i(iLineWidth05, s[1] - iLineWidth); glVertex2i(iLineWidth05, iLineWidth); glEnd(); } glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glLineWidth(oldLineWidth); glPopAttrib(); }
void SoXipCPUMprRender::GLRender(SoGLRenderAction * action) { SoState *state = action->getState(); SbViewportRegion vpRegion = SoViewportRegionElement::get(state); SbVec2s vpSize = vpRegion.getViewportSizePixels(); // Don't do anything if 0 size if (!vpSize[0] || !vpSize[1]) return; // Bind texture to available texture stage if (!mMPRTexId) glGenTextures(1, &mMPRTexId); int texUnit = SoXipMultiTextureElement::getFreeUnit(state); SoXipMultiTextureElement::setUnit(state, texUnit); SoXipMultiTextureElement::bindTexture(state, GL_TEXTURE_2D, mMPRTexId); // Check the size against min/max SbVec2s minmax = minMaxSize.getValue(); int which = (vpSize[0] > vpSize[1]) ? 0 : 1; float ratio = (float) vpSize[which] / (float) vpSize[1 - which]; // If smallest dim is < min if (vpSize[1 - which] < minmax[0]) { // Clamp to min and change biggest dim according to aspect ratio vpSize[1 - which] = minmax[0]; vpSize[which] = (short) (ratio * vpSize[1 - which]); } // If biggest dim is > max if (vpSize[which] > minmax[1]) { // Clamp to max and change smallest dim according to aspect ratio vpSize[which] = minmax[1]; vpSize[1 - which] = (short) (vpSize[which] / ratio); } // Ready the buffers readyBuffers(state); if (vpSize[0] == 0 || vpSize[1] == 0) return; // Check if mpr texture must be resized if (mMPRSize != vpSize) { resizeBuffers(vpSize); mUpdateFlag |= UPDATE_MPRCACHE; } // Exit if unsupported image type if (mTexInternalFormat == 0 || mTexType == 0) return; // Check if orientation has changed SbVec3f corners[4]; SbViewVolume viewVolume = SoViewVolumeElement::get(state); float dist = viewVolume.getNearDist() + viewVolume.getDepth() * 0.5f; corners[0] = viewVolume.getPlanePoint(dist, SbVec2f(0, 1)); corners[1] = viewVolume.getPlanePoint(dist, SbVec2f(1, 1)); corners[2] = viewVolume.getPlanePoint(dist, SbVec2f(1, 0)); corners[3] = viewVolume.getPlanePoint(dist, SbVec2f(0, 0)); if (corners[0] != mCorners[0] || corners[1] != mCorners[1] || corners[2] != mCorners[2] || corners[3] != mCorners[3]) { mCorners[0] = corners[0]; mCorners[1] = corners[1]; mCorners[2] = corners[2]; mCorners[3] = corners[3]; mUpdateFlag |= UPDATE_MPRCACHE; } // if (mUpdateFlag & UPDATE_MPRCACHE) { // Compute new cache table and mpr switch (mVolDataType) { case SbXipImage::UNSIGNED_BYTE: mLutBuf ? computeMPRCacheLUT(this, (unsigned char*)mVolBuf, state) : computeMPRCache(this, (unsigned char*)mVolBuf, state); break; case SbXipImage::BYTE: mLutBuf ? computeMPRCacheLUT(this, (char*)mVolBuf, state) : computeMPRCache(this, (char*)mVolBuf, state); break; case SbXipImage::UNSIGNED_SHORT: mLutBuf ? computeMPRCacheLUT(this, (unsigned short*)mVolBuf, state) : computeMPRCache(this, (unsigned short*)mVolBuf, state); break; case SbXipImage::SHORT: mLutBuf ? computeMPRCacheLUT(this, (short*)mVolBuf, state) : computeMPRCache(this, (short*)mVolBuf, state); break; case SbXipImage::UNSIGNED_INT: mLutBuf ? computeMPRCacheLUT(this, (unsigned int*)mVolBuf, state) : computeMPRCache(this, (unsigned int*)mVolBuf, state); break; case SbXipImage::INT: mLutBuf ? computeMPRCacheLUT(this, (int*)mVolBuf, state) : computeMPRCache(this, (int*)mVolBuf, state); break; case SbXipImage::FLOAT: mLutBuf ? computeMPRCacheLUT(this, (float*)mVolBuf, state) : computeMPRCache(this, (float*)mVolBuf, state); break; case SbXipImage::DOUBLE: mLutBuf ? computeMPRCacheLUT(this, (double*)mVolBuf, state) : computeMPRCache(this, (double*)mVolBuf, state); break; default: // will never come here cause we already checked for it in resize break; } // Update mpr texture updateTexture(); } else if (mUpdateFlag & UPDATE_MPR) { // Compute new mpr switch (mVolDataType) { case SbXipImage::UNSIGNED_BYTE: mLutBuf ? computeMPRLUT(this, (unsigned char*)mVolBuf) : computeMPR(this, (unsigned char*)mVolBuf); break; case SbXipImage::BYTE: mLutBuf ? computeMPRLUT(this, (char*)mVolBuf) : computeMPR(this, (char*)mVolBuf); break; case SbXipImage::UNSIGNED_SHORT: mLutBuf ? computeMPRLUT(this, (unsigned short*)mVolBuf) : computeMPR(this, (unsigned short*)mVolBuf); break; case SbXipImage::SHORT: mLutBuf ? computeMPRLUT(this, (short*)mVolBuf) : computeMPR(this, (short*)mVolBuf); break; case SbXipImage::UNSIGNED_INT: mLutBuf ? computeMPRLUT(this, (unsigned int*)mVolBuf) : computeMPR(this, (unsigned int*)mVolBuf); break; case SbXipImage::INT: mLutBuf ? computeMPRLUT(this, (int*)mVolBuf) : computeMPR(this, (int*)mVolBuf); break; case SbXipImage::FLOAT: mLutBuf ? computeMPRLUT(this, (float*)mVolBuf) : computeMPR(this, (float*)mVolBuf); break; case SbXipImage::DOUBLE: mLutBuf ? computeMPRLUT(this, (double*)mVolBuf) : computeMPR(this, (double*)mVolBuf); break; default: // will never come here cause we already checked for it in resize break; } // Update mpr texture updateTexture(); } // Render mpr to a quad renderMPR(texUnit); // Reset update flag mUpdateFlag = 0; }
void paintGL() { const SbViewportRegion vp = view->getSoRenderManager()->getViewportRegion(); SbVec2s size = vp.getViewportSizePixels(); glDisable(GL_LIGHTING); glViewport(0, 0, size[0], size[1]); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glDisable(GL_DEPTH_TEST); glClear(GL_COLOR_BUFFER_BIT); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, fbObject->texture()); glColor3f(1.0, 1.0, 1.0); GLfloat s = size[0] / GLfloat(fbObject->size().width()); GLfloat t = size[1] / GLfloat(fbObject->size().height()); glBegin(GL_QUADS); glTexCoord2f(0.0, 0.0); glVertex2f(-1.0, -1.0); glTexCoord2f(s, 0.0); glVertex2f(1.0, -1.0); glTexCoord2f(s, t); glVertex2f(1.0, 1.0); glTexCoord2f(0.0, t); glVertex2f(-1.0, 1.0); glEnd(); if (rubberBandIsShown) { glMatrixMode(GL_PROJECTION); glOrtho(0, size[0], size[1], 0, 0, 100); glMatrixMode(GL_MODELVIEW); glDisable(GL_TEXTURE_2D); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glLineWidth(4.0); glColor4f(1.0f, 1.0f, 1.0f, 0.2f); glRecti(rubberBandCorner1.x(), rubberBandCorner1.y(), rubberBandCorner2.x(), rubberBandCorner2.y()); glColor4f(1.0, 1.0, 0.0, 0.5); glLineStipple(3, 0xAAAA); glEnable(GL_LINE_STIPPLE); glBegin(GL_LINE_LOOP); glVertex2i(rubberBandCorner1.x(), rubberBandCorner1.y()); glVertex2i(rubberBandCorner2.x(), rubberBandCorner1.y()); glVertex2i(rubberBandCorner2.x(), rubberBandCorner2.y()); glVertex2i(rubberBandCorner1.x(), rubberBandCorner2.y()); glEnd(); glLineWidth(1.0); glDisable(GL_LINE_STIPPLE); glDisable(GL_BLEND); } glEnable(GL_LIGHTING); glEnable(GL_DEPTH_TEST); }
virtual void apply(SoNode* node) { if (!headlightRot) { SoSearchAction sa; sa.setNode(viewer->getHeadlight()); sa.apply(viewer->getSceneRoot()); SoFullPath* fullPath = (SoFullPath*) sa.getPath(); if (fullPath) { SoGroup *group = (SoGroup*) fullPath->getNodeFromTail(1); headlightRot = (SoRotation*) group->getChild(0); if (!headlightRot->isOfType(SoRotation::getClassTypeId())) headlightRot = 0; } } const SbViewportRegion vpr = getViewportRegion(); const SbVec2s & size = vpr.getViewportSizePixels(); const int width = size[0]; const int height = size[1]; const int vpsize = width / 2; SoCamera * camera = viewer->getCamera(); const SbVec3f position = camera->position.getValue(); const SbRotation orientation = camera->orientation.getValue(); const float nearplane = camera->nearDistance.getValue(); const float farplane = camera->farDistance.getValue(); camera->enableNotify(false); // Front View rotateCamera(SbRotation(SbVec3f(0,0,1), M_PI)); SbViewportRegion vp; vp.setViewportPixels(SbVec2s(0, height-width/2), SbVec2s(width, width/2) ); setViewportRegion(vp); SoGLRenderAction::apply(node); // Left View SbRotation r1(SbVec3f(0,0,1), -M_PI/2); rotateCamera(r1*SbRotation(SbVec3f(0,1,0), -M_PI/2)); vp.setViewportPixels(SbVec2s(0, height-width), SbVec2s(width/2, width) ); setViewportRegion(vp); SoGLRenderAction::apply(node); // Right View rotateCamera(SbRotation(SbVec3f(0,1,0), -M_PI)); vp.setViewportPixels(SbVec2s(width/2, height-width), SbVec2s(width/2, width) ); setViewportRegion(vp); SoGLRenderAction::apply(node); setViewportRegion(vpr); camera->position = position; camera->orientation = orientation; camera->enableNotify(true); // Restore original viewport region setViewportRegion(vpr); }