CompositeComponent *CompositeComponent::clone() const{ CompositeComponent* product = new CompositeComponent; for(size_t i = 0; i < this->size(); ++i){ product->addComponent(std::shared_ptr<Component>(m_children[i]->clone())); } return product; }
Component CaseFactory::addHoleForPort(const Component & component, double partOuterHeight, const PortDescription & port) { double off_xy = walls + space; // u is the vector facing in the positive axis parallel to the side (orthogonal to both n and the z axis) // v is the vector which is used for the port's local point's y coordinate and faces away from the board surface. Vec u = sidePositiveTangentialVector(port.side); Vec v = {0, 0, -1}; // The base position of a port, if it has a local point of (0,0). This is the "origin" of the side. Vec base = {0, 0, partOuterHeight}; if (port.side == North) { base.y = board.size[1]; } if (port.side == East) { base.x = board.size[0]; } // The hole is a hull of translated cylinders, so the hole is a rounded shape with radius port.radius along port.path [If the radius is 0, we use a tiny cylinder with 4 faces] Component cyl = Cylinder(std::max(port.radius, .001), off_xy + 2 * eps, port.radius == 0 ? 4 : 32, false); cyl.translate(0, 0, -eps); // Added by: Anthony W. Rainer <*****@*****.**> if(port.side != Flat) { cyl.rotateEulerZXZ(0.0, -90.0, -90.0 * port.side); }else{ cyl.rotateEulerZXZ(0.0, 180.0, 0); } // Add a cone for diagonal borders of the port hole double coneLength = off_xy - port.outset; Component cone = Cylinder(port.radius, port.radius + coneLength + 2 * eps, coneLength + 2 * eps, 32, false); cone.translate(0, 0, port.outset); // Added by: Anthony W. Rainer <*****@*****.**> if(port.side != Flat) { cone.rotateEulerZXZ(0.0, -90.0, -90.0 * port.side); }else{ cone.rotateEulerZXZ(0.0, 180.0, 0); } // Build convex hull of translated copies of this cylinder along the path of the port CompositeComponent cylHull = Hull::create(); CompositeComponent coneHull = Hull::create(); for (auto localPoint : port.path) { Vec p; // Added by: Anthony W. Rainer <*****@*****.**> if(port.side != Flat) { p = base + localPoint.x*u + localPoint.y*v; } else { p.z = off_xy; p.x = localPoint.x; p.y = localPoint.y; } Component thisCyl = cyl.translatedCopy(p.x, p.y, p.z); cylHull.addComponent(thisCyl); Component thisCone = cone.translatedCopy(p.x, p.y, p.z); coneHull.addComponent(thisCone); } return component - (cylHull + coneHull); }
String::String(string cad, double font_size, double spacing, double height) : Component() { data._string=cad; data._height=height; data._spacing = spacing; data._font_size=font_size; CompositeComponent comp = Union::create(); for (int i=0; i<data._string.size();i++){ Char ch(data._string.at(i),data._font_size,data._height); ch.translate(i*data._spacing,0,0); comp << ch; } data._created=true; set(comp.get()); }
Component CaseFactory::constructPart(Side whichSide) { // Select parameters depending on which part to build auto innerHeight = (whichSide == BottomSide) ? bottomInnerHeight() : topInnerHeight(); auto outerHeight = (whichSide == BottomSide) ? bottomHeight() : topHeight(); auto forbiddenAreas = (whichSide == BottomSide) ? board.bottomForbiddenAreas : board.topForbiddenAreas; auto ports = (whichSide == BottomSide) ? board.bottomPorts : board.topPorts; auto wallSupports = (whichSide == BottomSide) ? board.bottomWallSupports : board.topWallSupports; auto extension = (whichSide == outerExtensionOnSide) ? ExtensionOutside : ExtensionInside; auto screwHoleRadius =((whichSide == screwHeadsOnSide) ? holesAddRadiusLoose : holesAddRadiusTight) + board.holesRadius; auto screwHeads = (whichSide == screwHeadsOnSide); // We start with the base Component c = constructBase(innerHeight, extension); // Add wall support for (auto wallSupport : wallSupports) { c = addWallSupport(c, outerHeight, wallSupport); } // Screw holes for (auto hole : board.holes) { c = addHoleForScrew(c, outerHeight, hole, screwHoleRadius, screwHeads); } // Added by: Anthony W. Rainer <*****@*****.**> // Modified by: Bogdan Vacaliuc <*****@*****.**> to allow selection of side if(whichSide == board.holeNutsSide) { // Screw holes Nuts for (auto holeNut : board.holeNuts) { c = addCavityForNut(c, outerHeight, board.holes[holeNut.holeIndex], holeNut); } } // Apply rounded corners (if enabled) if (cornerRadius > 0.0) { // Class "RoundedCube" of ooml is buggy as it doesn't respect the "faces" parameter. // So we construct our own rounded cuboid by taking the convex hull of eight spheres. Vec min = {-outset(), -outset(), 0}; Vec max = outerDimensions() + min; Vec cornerOffset = {cornerRadius, cornerRadius, cornerRadius}; min += cornerOffset; max -= cornerOffset; CompositeComponent roundedCorners = Hull::create(); for (int corner = 0; corner < 8; corner++) { double x = (corner & (1 << 0)) ? min.x : max.x; double y = (corner & (1 << 1)) ? min.y : max.y; double z = (corner & (1 << 2)) ? min.z : max.z; roundedCorners.addComponent(Sphere(cornerRadius, cornerFaces).translatedCopy(x, y, z)); } // Intersect the current part with the rounded cuboid c = c * roundedCorners; } // Port holes for (auto port : ports) { c = addHoleForPort(c, outerHeight, port); } // "Forbidden areas" of the board for (auto area : forbiddenAreas) { c = c - Cube(area.sx, area.sy, area.sz + extensionHeight() + eps, false) .translatedCopy(area.x, area.y, outerHeight - area.sz); } // If this is the top, we've just built it mirrored. So we mirror the y axis and move it so it matches the dimensions of the bottom part. if (whichSide == TopSide) { c.scale(1.0, -1.0, 1.0); c.translate(0.0, board.size[1], 0.0); } return c; }