/*************************************************************************** * Copyright (c) 2004 Jürgen Riegel * * * * This file is part of the FreeCAD CAx development system. * * * * This library is free software; you can redistribute it and/or * * modify it under the terms of the GNU Library General Public * * License as published by the Free Software Foundation; either * * version 2 of the License, or (at your option) any later version. * * * * This library is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; see the file COPYING.LIB. If not, * * write to the Free Software Foundation, Inc., 59 Temple Place, * * Suite 330, Boston, MA 02111-1307, USA * * * ***************************************************************************/ #include "PreCompiled.h" #ifndef _PreComp_ # include # include # include # include # include # include # include # include #endif #include #include #include #include #include #include #include #include #include #include #include "View3DInventorExamples.h" unsigned char * generateTexture(int w, int h, int d) { int val; float x,y,z; // unsigned char pixval; auto bitmap = new unsigned char[w*h*d]; for (int k = 0;k= 256) val = 511-val; bitmap[k*w*h + j*h + i] = val; } } } return bitmap; } void doClipping(SbVec3f trans, SbRotation rot) { SbMatrix mat; SbVec3f normal; mat.setTransform(trans, rot, SbVec3f(1,1,1)); mat.multDirMatrix(SbVec3f(0, -1, 0), normal); SbPlane plane(normal, trans); const float coords[][3] = { {-5,-5,-5}, {5,-5,-5}, {5,5,-5}, {-5,5,-5}, {-5,-5,5}, {5,-5,5}, {5,5,5}, {-5,5,5} }; const int indices[] = { 0,3,2,1,-1, 0,1,5,4,-1, 2,6,5,1,-1, 3,7,6,2,-1, 3,0,4,7,-1, 7,4,5,6,-1 }; // Clip box against plane SbClip clip; SoMFVec3f * globalVerts = (SoMFVec3f *)SoDB::getGlobalField(SbName("globalVerts")); SoMFVec3f * globalTVerts = (SoMFVec3f *)SoDB::getGlobalField(SbName("globalTVerts")); SoMFInt32 * globalnv = (SoMFInt32 *)SoDB::getGlobalField(SbName("globalnv")); globalVerts->startEditing(); globalVerts->setNum(0); globalTVerts->startEditing(); globalTVerts->setNum(0); globalnv->startEditing(); globalnv->setNum(0); int i; for (i = 0;i<6*5;i++) { if (indices[i] == -1) { clip.clip(plane); int numVerts = clip.getNumVertices(); if (numVerts > 0) { for (int j = 0;jset1Value(globalVerts->getNum(), v); v += SbVec3f(5, 5, 5); v /= 10.0; globalTVerts->set1Value(globalTVerts->getNum(), v); } globalnv->set1Value(globalnv->getNum(), numVerts); } clip.reset(); } else clip.addVertex(coords[indices[i]]); } globalVerts->finishEditing(); globalTVerts->finishEditing(); globalnv->finishEditing(); // Close hole in clipped box by clipping against all 6 planes const SbVec3f planecoords[] = { SbVec3f(-10,0,-10), SbVec3f(10,0,-10), SbVec3f(10,0,10), SbVec3f(-10,0,10) }; clip.reset(); for (i = 0;i<4;i++) { SbVec3f v; mat.multVecMatrix(planecoords[i], v); clip.addVertex(v); } for (i = 0;i<6*5;i+=5) { SbPlane p(coords[indices[i+2]], coords[indices[i+1]], coords[indices[i]]); clip.clip(p); } int numVerts = clip.getNumVertices(); SoMFVec3f * planeVerts = (SoMFVec3f *)SoDB::getGlobalField(SbName("planeVerts")); SoMFVec3f * planeTVerts = (SoMFVec3f *)SoDB::getGlobalField(SbName("planeTVerts")); planeVerts->startEditing(); planeVerts->setNum(0); planeTVerts->startEditing(); planeTVerts->setNum(0); for (i = 0;iset1Value(planeVerts->getNum(), v); v += SbVec3f(5, 5, 5); v /= 10.0; planeTVerts->set1Value(planeTVerts->getNum(), v); } planeVerts->finishEditing(); planeTVerts->finishEditing(); } void draggerCB(void * /*data*/, SoDragger * dragger) { auto drag = (SoTransformerDragger *)dragger; doClipping(drag->translation.getValue(), drag->rotation.getValue()); } void Texture3D(SoSeparator * root) { SoDB::createGlobalField("globalVerts", SoMFVec3f::getClassTypeId()); SoDB::createGlobalField("globalTVerts", SoMFVec3f::getClassTypeId()); SoDB::createGlobalField("globalnv", SoMFInt32::getClassTypeId()); SoDB::createGlobalField("planeVerts", SoMFVec3f::getClassTypeId()); SoDB::createGlobalField("planeTVerts", SoMFVec3f::getClassTypeId()); doClipping(SbVec3f(0,0,0), SbRotation()); // SoSeparator * root = new SoSeparator; // root->ref(); auto comp = new SoComplexity; comp->textureQuality.setValue((float)0.9); root->addChild(comp); auto texture = new SoTexture3; texture->wrapR.setValue(SoTexture3::CLAMP); texture->wrapS.setValue(SoTexture3::CLAMP); texture->wrapT.setValue(SoTexture3::CLAMP); // SbString filenames[64]; // for (int i=0;i<64;i++) // filenames[i].sprintf("../../../data/pgmvol/slice%02d.raw.pgm",i); // texture->filenames.setValues(0,64,filenames); unsigned char * img = generateTexture(256,256,256); texture->images.setValue(SbVec3s(256,256,256), 1, img); root->addChild(texture); auto mat = new SoMaterial; mat->emissiveColor.setValue(1,1,1); root->addChild(mat); auto dragger = new SoTransformerDragger; dragger->scaleFactor.setValue(5,5,5); dragger->addValueChangedCallback(draggerCB, nullptr); root->addChild(dragger); auto clippedCoords = new SoCoordinate3; clippedCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("globalVerts")); root->addChild(clippedCoords); auto clippedTCoords = new SoTextureCoordinate3; clippedTCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("globalTVerts")); root->addChild(clippedTCoords); auto clippedFS = new SoFaceSet; clippedFS->numVertices.connectFrom((SoMFInt32 *) SoDB::getGlobalField("globalnv")); root->addChild(clippedFS); auto planeCoords = new SoCoordinate3; planeCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("planeVerts")); root->addChild(planeCoords); auto planeTCoords = new SoTextureCoordinate3; planeTCoords->point.connectFrom((SoMFVec3f *) SoDB::getGlobalField("planeTVerts")); root->addChild(planeTCoords); auto planeFS = new SoFaceSet; root->addChild(planeFS); } // ************************************************************************* static const char scenegraph[] = "#Inventor V2.1 ascii\n" "Separator {\n" " DEF RedLight PointLight { location -10 -10 10 color 1 0 0 }\n" " DEF GreenLight PointLight { location -5 5 10 color 0 1 0 }\n" " DEF BlueLight PointLight { location 10 10 10 color 0 0 1 }\n" " Material { diffuseColor 0.5 0.5 0.5 specularColor 1 1 1 }\n" " Array {\n" " origin CENTER\n" " numElements1 3 separation1 5.5 0 0\n" " numElements2 3 separation2 0 5.5 0\n" "\n" " Sphere { radius 3 }\n" " }\n" "}\n"; void LightManip(SoSeparator * root) { SoInput in; in.setBuffer((void *)scenegraph, std::strlen(scenegraph)); SoSeparator * _root = SoDB::readAll( &in ); if (!_root) // Shouldn't happen. return; root->addChild(_root); root->ref(); const char * pointlightnames[3] = { "RedLight", "GreenLight", "BlueLight" }; SoSearchAction sa; for (const char* name : pointlightnames) { sa.setName(name); sa.setInterest( SoSearchAction::FIRST ); sa.setSearchingAll( false ); sa.apply( root ); SoPath * path = sa.getPath(); if (!path) // Shouldn't happen. return; auto manip = new SoPointLightManip; manip->replaceNode( path ); } } /***********************************************************************************************************/ // Global constants const int texturewidth = 128; const int textureheight = 128; // Global variables double global_cr = 0.33; double global_ci = 0.43; // Global pointer //unsigned char * bitmap = new unsigned char[texturewidth*textureheight]; unsigned char bitmap[texturewidth*textureheight]; // Function to generate a julia set // Parameters: // double cr - real part of the julia set point // double ci - imaginary part of the julia set point // float zoom - length of the square to display (zoom*zoom), center (0,0) // int width - width of the bitmap // int height - height of the bitmap // int mult - number to multiply each color by. // unsigned char * bmp - pointer to the bitmap // int n - number of iterations void julia(double crr, double cii, float zoom, int width, int height, int mult, unsigned char * bmp, int n) { double zr, zr_old, zi; int w; for (int y=0; yimage.setValue(SbVec2s(texturewidth, textureheight), 1, bitmap); texture->model = SoTexture2::MODULATE; texture->blendColor.setValue(1.0, 0.0, 0.0); return texture; } // This function is called 20 times each second. static void timersensorcallback(void * data, SoSensor *) { static SbBool direction = false; auto texnode = (SoTexture2*) data; if (!direction) { global_cr -= 0.0005; global_ci += 0.0005; } else { global_cr += 0.0005; global_ci -= 0.0005; } if (global_ci<0.30) direction = !direction; else if (global_ci>0.83) direction = !direction; SbVec2s size; int nc; unsigned char * image = texnode->image.startEditing(size, nc); // Generate a julia set to use as a texturemap julia(global_cr, global_ci, 2.5, size[0], size[1], 4, image, 64); texnode->image.finishEditing(); } void AnimationTexture(SoSeparator * root) { // Scene graph if (!root) // Shouldn't happen. return; // Generate a julia set to use as a texturemap julia(global_cr, global_ci, 2.5, texturewidth, textureheight, 4, bitmap, 64); SoTexture2 * texnode = texture(); // Enable backface culling auto hints = new SoShapeHints; hints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE; hints->shapeType = SoShapeHints::SOLID; // Timer sensor auto texturetimer = new SoTimerSensor(timersensorcallback, texnode); texturetimer->setInterval(0.05); texturetimer->schedule(); root->ref(); // prevent from being deleted because of the still running timer sensor // SoSeparator * root = new SoSeparator; // root->ref(); root->addChild(hints); root->addChild(texnode); root->addChild(new SoCube); }