chandlerprall / ThreeCSG

CSG plugin for Three.js
MIT License
453 stars 152 forks source link

Mash materials together in new mesh #13

Open paulbrzeski opened 10 years ago

paulbrzeski commented 10 years ago

I want to create an indoor room area using the ThreeCSG plugin. The challenge I'm up to is windows. I'd like to be able to union a window frame cube into the room and then subtract a 'glass' cube.

Is there was a way for me to retain the materials from the original shape? In the scenario above, I'd like to be able to retain the wall, window frame and glass materials.

paulbrzeski commented 10 years ago

I've been able to get this working by building an array of the materials going in and then assigning material Indexes based on that array. I've hijacked the ThreeBSP.Polygon.prototype.calculateProperties method to always pass in a materialIndex.

Code: https://github.com/paulbrzeski/Langenium/blob/master/public/scripts/scenograph/director/sandbox.js 132-154

Demo: (activeScene needs to be set to "Sandbox") http://staging.langenium.com/

Not sure how that would integrate with this plugin though... It seems more of a wraparound thing?

tarun29061990 commented 9 years ago

I am working on the same thing. I am trying to fit the door in the wall by subtracting door from wall. But no luck. Please help ?

paulbrzeski commented 7 years ago

Hey @tarun29061990, can you elaborate a bit more on the exact issue? Were you having trouble with just the geometry or was it with the materials?

I ended up implementing an extra attribute on each mesh face called materialIndex and creating a materials array (MeshFaceMaterial in today's THREE.. i think?), the material index in the array then being assigned to each faces' materialIndex.

https://github.com/paulbrzeski/Langenium/blob/master/old/src/scenograph/editor.js#L38

Then in CSG, I had to make some changes to handle the materialIndex so that it'd be preserved. I changed a few lines so just do a search for that var name and you'll see where that value has to be placed and handled in your own copy... potentially :P https://github.com/paulbrzeski/Langenium/blob/master/old/src/vendor/ThreeCSG.js

@chandlerprall, is multi material support in? If not, I'll whip up a proper pull request for ya :)

dghez commented 5 years ago

I'm struggling with the same problem, I created a subtract mesh (a simple cube subtract from another cube) but when I try to create a texture on only specific faces looks like the array of materials isn't useful, it takes value from only the material in 0 position (three r97, the MeshFaceMaterial is deprecated btw, now you just need to pass the array of materials).

EDIT:

I ended up taking @paulbrzeski version of the plugin AND then

   // set each faces with an index
    final.geometry.faces.forEach(function (face, i) {
      face.materialIndex = i
    })

    let materialsArr = []
    for (let i = 0; i < final.geometry.faces.length; i++) {
      let mat = basicMaterial

      // find the faces I need to modify
      if (i > 23 && i < 34) {
        mat = patternMaterial
      }

      // add to the final array
      materialsArr.push(mat)
    }

    // no need MeshFaceMaterial anymore, just an array
    final.material = materialsArr

This approach is kinda unconvenient because it's difficult to find the rights faces to apply the different material, in my case (a simple composition) I have like 58 faces, so I looped through all of them to find the right ones.