I am developing a sample application in which iam using vtkplanes to crop the surfaceRendered output.
The changes are visualizing on the vtkRenderWindow clearly without any problem,but when i convert it into stl file the cropped changes are not saved instead it is saving the 3D object before i made the cropping.
here is my code
mapper->SetInputConnection( surfaceRenderedOutput->GetOutputPort() );
mapper->AddClippingPlane( plane6 );
mapper->AddClippingPlane( plane1 );
mapper->AddClippingPlane( plane2 );
mapper->AddClippingPlane( plane3 );
mapper->AddClippingPlane( plane5 );
mapper->AddClippingPlane( plane4 );
mapper->Update();
surfaceRenderedOutput->SetInputConnection(mapperr->GetOutputPort());
surfaceRenderedOutput->Update();
To write to stl i used like this
stlWriter->SetInput(surfaceRenderedOutput->GetOutput());
stlWriter->Write();
Can anyone help please
EDIT
I did like this
//vtkClipPolyData//
clipper1->SetClipFunction(plane1);
clipper2->SetClipFunction(plane2);
clipper3->SetClipFunction(plane3);
clipper4->SetClipFunction(plane4);
clipper5->SetClipFunction(plane5);
clipper6->SetClipFunction(plane6);
polyd1=clipper1->GetOutput();
polyd2=clipper2->GetOutput();
polyd3=clipper3->GetOutput();
polyd4=clipper4->GetOutput();
polyd5=clipper5->GetOutput();
polyd6=clipper6->GetOutput();
vtkSmartPointer<vtkAppendPolyData> appendFilter =
vtkSmartPointer<vtkAppendPolyData>::New();
appendFilter->SetNumberOfInputs(6);
appendFilter->AddInput(polyd1);
appendFilter->AddInput(polyd2);
appendFilter->AddInput(polyd3);
appendFilter->AddInput(polyd4);
appendFilter->AddInput(polyd5);
appendFilter->AddInput(polyd6);
appendFilter->Update();
stlWriter->SetInput(appendFilter->GetOutput());
still im not getting the output
The mapper doesn't do anything to the surfaceRenderedOutput. The output of the mapper presumably goes to a vtkActor which then goes to the vtkRenderWindow.
You want the output of the mapper. What is its type?
For the vtkClipPolyData object there is a getClippedOutput method which should allow you to get a clipped mesh.
Related
I have a scene in Three (using AFrame) that requires environment mapping for lighting. Using a standard HDR cubemap, I get the following results:
This is correct as far as blurring based on roughness goes, since I have mipmaps being generated and the minFilter set to LinearMipmapLinearFilter. The issue with this approach is that ambient lighting isn't being applied - the light in the scene, a directional light, is the only thing providing any lighting information to the scene. Unfortunately, this results in entirely black shadows, no matter how bright the HDRI.
However, if I use the PMREMGenerator from Three in addition to the above, the ambient lighting issue is solved. Unfortunately, this is what happens as a result:
As shown here, the texture filtering is now out of whack. According to comments left in the PMREMGen script itself.
This class generates a Prefiltered, Mipmapped Radiance Environment Map (PMREM) from a cubeMap environment texture. This allows different levels of blur to be quickly accessed based on material roughness. It is packed into a special CubeUV format that allows us to perform custom interpolation so that we can support nonlinear formats such as RGBE. Unlike a traditional mipmap chain, it only goes down even more filtered 'mips' at the same LOD_MIN resolution, associated with higher roughness levels. In this way we maintain resolution to smoothly interpolate diffuse lighting while limiting sampling computation.
...which leads me to believe the output should be smoothed, like in my first example.
Here's my code for the first example:
const ctl = new HDRCubeTextureLoader();
ctl.setPath(hdrPath);
ctl.setDataType(THREE.UnsignedByteType);
const hdrUrl = [
`${src}/px.hdr`,
`${src}/nx.hdr`,
`${src}/py.hdr`,
`${src}/ny.hdr`,
`${src}/pz.hdr`,
`${src}/nz.hdr`
];
const hdrSky = ctl.load(hdrUrl, tex => this.skies[src] = hdrSky );
// Then later...
obj.material.envMap = this.skies[this.skySources[index]];
obj.material.needsUpdate = true;
Here's my code for the second example:
const ctl = new HDRCubeTextureLoader();
ctl.setPath(hdrPath);
ctl.setDataType(THREE.UnsignedByteType);
const hdrUrl = [
`${src}/px.hdr`,
`${src}/nx.hdr`,
`${src}/py.hdr`,
`${src}/ny.hdr`,
`${src}/pz.hdr`,
`${src}/nz.hdr`
];
const pmremGen = new PMREMGenerator(this.el.sceneEl.renderer);
pmremGen.compileCubemapShader();
const hdrSky = ctl.load(hdrUrl, tex => {
const hdrRenderTarget = pmremGen.fromCubemap(hdrSky);
this.skies[src] = hdrRenderTarget.texture;
});
// Then later...
obj.material.envMap = this.skies[this.skySources[index]];
obj.material.needsUpdate = true;
I seem to have hit a wall in regard to the filtering. Even when I explicitly change the filtering type and turn on mipmap generation inside of PMREMGenerator.js, the results appear to be the same. Here's an official example that uses the PMREMGenerator without any issue: https://threejs.org/examples/webgl_materials_envmaps_hdr.html
As a closing remark I will note that we're using Three.js r111 (and there are reasons we can't switch it out fully), so I brought in the current version of the PMREMGenerator from the latest version of Three as of this writing (r122 - later version needed as the r111 one is written completely differently). Thus, I wouldn't be surprised if this was all being caused by some conflict between versions.
EDIT: Just put the resulting envmap as a standard map on some planes, and much to my surprise none of the blurred LODS even show up. Here's what mine look like:
And here's what it should resemble (don't mind the torus knot):
EDIT: I've found a workaround for now (essentially, not using PMREMGenerator), but will leave this up in case a solution is discovered.
I believe the problem is with the argument you're using in fromCubemap(). Right now your code isn't using the tex cubetexture variable that's passed to the loaded callback. Try this:
const hdrSky = ctl.load(hdrUrl, tex => {
// use tex instead of hdrSky
const hdrRenderTarget = pmremGen.fromCubemap(tex);
this.skies[src] = hdrRenderTarget.texture;
});
I am working on a POC in which I have to customize a watch in 3d model.
I am using thee.js for doing webgl stuff. I was able to change strap color , dial color and load texture images on strap. But I am stuck when I try to add dynamic text on the the watch , I have to update text on watch's back dial as user types in Engrave Text text box . For this I tried https://github.com/jeromeetienne/threex.dynamictexture library , which works on a new geometry but I am not able to add it watch's existing model.
I have pushed all code in github : https://github.com/bhupendra1011/watch-3d-engrave , as I was not able to load external 3d models from my fiddle account {CORS issue}.
Demo of the POC can be seen here : https://bhupendra1011.github.io/watch-3d-engrave/index.html
Below is the code to add text on watch dial; For loading text click on use textures textbox in index.html
function engraveTextOnWatch(val = "IWC") {
dynamicTexture = new THREEx.DynamicTexture(512, 512);
dynamicTexture.context.font = "bolder 90px Verdana";
// watch back dial geometry & material where text needs to be engraved
var backDialGeometry = object3d.children[1].children[0].children[0].geometry;
var backDialMaterial = object3d.children[1].children[0].children[0].material;
// geometry to add dynamic text
var geometry = new THREE.CubeGeometry(1, 1, 1);
var material = new THREE.MeshBasicMaterial({
map: dynamicTexture.texture
});
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh); // adding mesh to scene , but this needs to be attache to watch's back dial geomtry
/* tried adding dynamicTexture to watch back dial material, but this is not working , text not appearing */
//backDialMaterial.map = dynamicTexture.texture;
dynamicTexture.texture.needsUpdate = true;
dynamicTexture.drawText(val, 2, 256, "orange");
}
Kindly let me know how can I add dynamic text on existing model.
Thanks.
I was able to reproduce your problem in Blender and it comes from your model's UV map.
I downloaded your model, opened it in Three.js editor and converted it to .obj to open it in blender to reproduve your problem
As you can see on the image, applying a texture is just as messy. You need to rework the model's uvmap to achieve the desired effect like so (I used a random image from your folder)
And while you're at it, you might want to consider optimizing your model, which is pretty heavy and could be simplified for faster load without losing visual quality (but it's entirely up to you, I'm just suggesting).
Here's the current model
Here's a quick possible replacement. Cylinder that's open on one end and beveled on the edge loop
I'm trying to figure how to use the EffectComposer in ThreeJS.
Trying to apply motion blur to a mesh while keeping the background mesh sharp.
The only way I sort of was able to get it to work was by losing depth with the background overlapping the front elements:
http://code.michael-iriarte.com/post-process-test/test-1.html
But I'd like to be able to render something more like that (but with the motion blur):
http://code.michael-iriarte.com/post-process-test/test-2.html
See two examples below:
composerBack.addPass( renderBack );
composerFront.addPass( renderFront );
composerFront.addPass( renderMaskInverseFront );
composerFront.addPass( effectHBlur );
composerFront.addPass( effectVBlur );
composerFront.addPass( clearMask );
composerMerge.addPass( rttPassBack );
// composerMerge.addPass( renderMaskInverseBack );
composerMerge.addPass( renderMaskFront );
composerMerge.addPass( rttPassFront );
composerMerge.addPass( clearMask );
composerMerge.addPass( effectCopy);
Some help on the topic would be very welcome!
Well, this is a bit weird talking to myself on Stackoverflow :)
All I was missing was:
rttPassFront = new THREE.TexturePass( composerFront.renderTarget2.texture );
rttPassFront.material.transparent = true;
See a demo here:
http://code.michael-iriarte.com/post-process-test/solution-1.html
I hope it helps others. If you have different approach, please share!!
I need to export Three Geometry to JSON so I can used with xml3D.
I am trying to find the THREE.GeometryExporter() but I can't. Has it been completely deprecated?
It is mentioned here
Once I have the Three JSON I should be able to use this converter to obtain the xml3D JSON.
Has anyone tried this before?
You should try the toJSON() method :
var json = geometry.toJSON();
This method is available for geometries, materials, lights, mesh ...
Realease 68 seems to be the last one with GeometyExporter in the examples folder.
https://github.com/mrdoob/three.js/tree/r68/examples/js/exporters
Not sure how you expect it to output to xml3D format (I've never tried it), though it should not be too hard to alter if need be.
This three.js json to xml3d converter may come in handy.
https://github.com/xml3d/threejs-to-xml3d
geometry.toJSON() wasn't outputting the information in the format I needed to do something similar. My solution was the following:
cannonPoints = geometry.vertices.map(function(v) {
return new CANNON.Vec3( v.x, v.y, v.z )
})
cannonFaces = geometry.faces.map(function(f) {
return [f.a, f.b, f.c]
})
I shared this solution on a similar problem here:
Create CANNON.RigidBody from THREE.Mesh or THREE.Geometry
For some time, I've been trying to figure out how to do an object selection outline in my game. (So the player can see the object over everything else, on mouse-over)
This is how the result should look:
The solution I would like to use goes like this:
Layer 1: Draw model in regular shading.
Layer 2: Draw a copy in red color, scaled along normals using vertex shader.
Mask: Draw a black/white flat color of the model to use it as a stencil mask for the second layer, to hide insides and show layer 1.
And here comes the problem. I can't really find any good learning materials about masks. Can I subtract the insides from the outline shape? What am I doing wrong?
I can't figure out how to stack my render passes to make the mask work. :(
Here's a jsfiddle demo
renderTarget = new THREE.WebGLRenderTarget(window.innerWidth, window.innerHeight, renderTargetParameters)
composer = new THREE.EffectComposer(renderer, renderTarget)
// composer = new THREE.EffectComposer(renderer)
normal = new THREE.RenderPass(scene, camera)
outline = new THREE.RenderPass(outScene, camera)
mask = new THREE.MaskPass(maskScene, camera)
// mask.inverse = true
clearMask = new THREE.ClearMaskPass
copyPass = new THREE.ShaderPass(THREE.CopyShader)
copyPass.renderToScreen = true
composer.addPass(normal)
composer.addPass(outline)
composer.addPass(mask)
composer.addPass(clearMask)
composer.addPass(copyPass)
Also I have no idea whether to use render target or renderer for the source of the composer. :( Should I have the first pass in the composer at all? Why do I need the copy pass? So many questions, I know. But there are just not enough resources to learn from, I've been googling for days.
Thanks for any advice!
Here's a js fiddle with working solution. You're welcome. :)
http://jsfiddle.net/Eskel/g593q/6/
Update with only two render passes (credit to WestLangley):
http://jsfiddle.net/Eskel/g593q/9/
The pieces missing were these:
composer.renderTarget1.stencilBuffer = true
composer.renderTarget2.stencilBuffer = true
outline.clear = false
Now I think I've found a bit simpler solution, from the THREEx library. It pre-scales the mesh so you dont need a realtime shader for it.
http://jeromeetienne.github.io/threex.geometricglow/examples/geometricglowmesh.html