Mesh3D.combine creates a hole

I'm trying to build a thing that has a base floor, and two walls sticking up.  Each of the three pieces is a 3-space rectangle, but the walls are mostly inside the base.  (The floor point is z=0 for the walls, but the x,y coordinates are inside the boundaries of the base, not touching the x,y edges of the base.)  When I combine each wall to the base (using Mesh3d.combine()), I get a hole in the base.  If I were to do this using the UI of Tinkercad, it wouldn't do that.

I've seen other holes emitted from the system errantly (or so I think).  For example, I have a function that creates a cylinder mesh.  I create one big cylinder mesh, then a smaller one, and then transform the smaller one to sit directly atop the bigger one.  The result is a messy hole in the bigger one.  If I separate the two by a small amount, or bury the smaller cylinder down into the larger cylinder by a small amount, it doesn't appear to generate the hole.  With that case, I tried  "tesselating" (sort of) the cylinder function.  Originally, cylinder was comprised of 30 triangles on top (radius to edge), 30 on bottom, and then quads going around the sides.  The "tesselated" form added in lots of interim radii along the top, and seemed to make the hole more refined, but still there was a hole.

Anyway, the simple case is the walls-in-base.  Three rectangular 3-space objects, two embedded in base and touching the same z=0 floor, and I get a hole where they intersect.

Should I be trying to do this some other way?  I tried using combineByBoundaries but didn't get any better result with it.  I don't want to use unite() yet, because that's async and my code's not ready for that.  (Right now, I do synchronous combine calls within shapeGeneratorEvaluate(), and then if I need to subtract, I do that at the very end before calling the callback.)


 Top view


View from below



Code snippet (minus all the lead-up and parameter stuff):

// Renders box at unit size, then transforms to given parameter sizes.
function makeBoxMesh(wid,depth,hgt) {
  var sides = [];
  var mesh = new Mesh3D();
  sides.push([0,0,0]); // 0
  sides.push([1,0,0]); // 1
  sides.push([1,1,0]); // 2
  sides.push([0,1,0]); // 3
  sides.push([0,0,1]); // 4
  sides.push([1,0,1]); // 5
  sides.push([1,1,1]); // 6
  sides.push([0,1,1]); // 7

  var tm = new Matrix3D();
  return mesh;

function shapeGeneratorEvaluate(params, callback) {
  // var nSides = 10;
  var motorShaftDiameter  = 6;
  var motorShaftExtension = 18;
  var motorHoleDepth      = 9.35;

  var shaftDiameter = params['shaftdiameter'];
  var lift          = params['lift'];
  var stepWidth     = params['stepwidth'];
  var looseWidth    = params['loosewidth'];
  var wallWidth     = params['wallwidth'];
  var nSteps        = params['nsteps'];
  var motorHoleDiam = params['motorholediam'];
  var setScrewDiam  = params['setscrewdiam'];
  var setScrewOffset= params['setscrewoffset'];
  var wallDepth = shaftDiameter + 7;
  var motorHeight = 12;
  var bottomClearance = 11;
  var topClearance = 4; // cannot be bigger than smallest step height
  var baseHgt = 3;
  var baseDepth = wallDepth + 5;
  var baseWidth = 4.5 + wallWidth*2 + looseWidth + nSteps*stepWidth + 4.5;
  var shaftCenterZ = baseHgt + bottomClearance +
    Math.max(motorHeight/2 , lift+(shaftDiameter/2));
  var wallHgt = shaftCenterZ + (shaftDiameter/2) + lift + topClearance;
  var mainMesh = new Mesh3D();

  var leftMesh = makeBoxMesh(wallWidth, wallDepth, wallHgt);
  var leftWall_tm = new Matrix3D();
  var rightMesh = makeBoxMesh(wallWidth, wallDepth, wallHgt);
  var rightWall_tm = new Matrix3D();
  rightWall_tm.identity().translation(4.5 + wallWidth + nSteps*stepWidth + looseWidth,5.0/2,0);
  var baseMesh = makeBoxMesh(baseWidth, baseDepth, baseHgt);
  var base_tm = new Matrix3D();


  var x = Solid.make(mainMesh);


Please sign in to leave a comment.