Print at Aug 20, 2026, 9:54:45 PM
Posts: 97   Pages: 10   [ Previous Page | 1 2 3 4 5 6 7 8 9 10 ]
View all posts in this thread on one page
Posted by Xlance at Jun 27, 2026, 11:36:14 PM
Re: Staircase generator plug-in
@el_dario
Version 4.2 or later will be posted on sourceforge as soon as it's ready smile
----------------------------------------

Windows 64bit | Intel i7 | 8GB Ram | SH3D 7.5 + Plugins

Posted by el_dario at Jun 30, 2026, 12:38:05 PM
Re: Staircase generator plug-in
Thank you for your reply, @Xlance! I eagerly await the release of version 4.2, so I can try out these new features! :)

Posted by Xlance at Aug 7, 2026, 8:30:20 AM
Re: Staircase generator plug-in
NEW in version 4.2
Import Plan image of Staircase in 2D Shape Designer and Trace it to get Precise cutout *.svg path

1.CHOOSE Plan image of Staircase to Trace

2.TRACE then SAVE values of custom cutout into *.svg

3.LOAD *.svg file then COPY values of custom cutout

4.PASTE values of custom cutout into field (make sure to un-select 'generate cutout' check box)

5.CREATE staircase (custom cutout will be embedded with model)



Take screenshot
https://ibb.co/Hp7L50hg

Open 2D Shape Designer and choose image to load
https://ibb.co/kgcqv5DS

Trace outline/cutout then save in *.svg
https://ibb.co/hJPJcnb7

Load *.svg and copy values
https://ibb.co/SjhZx5Z

Paste values into custom cutout field (make sure to un-select 'generate cutout' check box)
https://ibb.co/21Pkb45G

Result
https://ibb.co/3Y0zDr4F
----------------------------------------

Windows 64bit | Intel i7 | 8GB Ram | SH3D 7.5 + Plugins

Posted by Keet at Aug 7, 2026, 9:53:06 AM
Re: Staircase generator plug-in
Why so difficult? You can easily calculate an SVG cutout string using the v lines in a room object (or any other object where an outline can be calculated from). It is much easier to draw a room then the screenshot copies. Here's the code for it in PHP and C#.
Both code listings are made to to be readable by non-programmers too. This was a test for me so a little optimization is probably possible.
The C# code is close to Java code so should be easy to convert.
The PHP code is amateur work, I only use it for my websites.

C# code:
using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;

namespace SH3D
{
public class SVG
{
// constructor
public SVG () {}

/// <summary>
/// Create an SVG cutout string from the given obj file
/// </summary>
/// <returns>
/// The SVG cutout string
/// </returns>
/// <param name='sourcefile'>
/// The obj file to use for creating the SVG string.
/// A cutout string is generated using the v lines in the first group, best result with a room object.
/// </param>
public string CreateSVGcutout (string sourcefile)
{
if (!File.Exists (sourcefile)) { return string.Empty; }

#region create vertice list
// Create an empty list to hold all vertices (v lines)
List<Vertice> vertices = new List<Vertice> ();

// Read all lines in the obj file into a string array
String[] lines = File.ReadAllLines (sourcefile);
bool start = false;

// For each line that starts with "v " create a Vertice object and add it to the vertices list.
// z is set to 0 by default, not used for a SVG cutout.
foreach (string line in lines) {
if (line.StartsWith ("v ")) {
start = true;
string[] parts = line.Split (new char[] {' '});
// 0 = "v", 1=X, 2=Z, 3=Y
Vertice v = new Vertice (double.Parse(parts [1]), double.Parse(parts [3]), 0.0d);
vertices.Add (v);
} else {
// First set of v lines done, ignore the rest
if (start) {
break;
}
}
}
#endregion create vertice list

#region object bounderies
// Get the object bounderies, I.E. the width and depth of the object
// These are needed to calculate the L points
// Calculating this enables processing objects that dont't have 0,0 as the position coordinates.
double minwidth = 0.0;
double maxwidth = 0.0;
double mindepth = 0.0;
double maxdepth = 0.0;
bool first = true;
foreach (Vertice v in vertices) {
if (first) {
minwidth = v.X;
maxwidth = v.X;
mindepth = v.Y;
maxdepth = v.Y;
first = false;
} else {
minwidth = Math.Min (minwidth, v.X);
maxwidth = Math.Max (maxwidth, v.X);
mindepth = Math.Min (mindepth, v.Y);
maxdepth = Math.Max (maxdepth, v.Y);
}
}

double width = 0.0d;
if (minwidth < 0) {
if (maxwidth < 0) { // - / -
width = Math.Abs (minwidth) - Math.Abs (maxwidth);
} else { // - / +
width = Math.Abs (minwidth) + maxwidth;
}
} else { // + / +
width = maxwidth - minwidth;
}

double depth = 0.0d;
if (mindepth < 0) {
if (maxdepth < 0) { // - / -
depth = Math.Abs (mindepth) - Math.Abs (maxdepth);
} else { // - / +
depth = Math.Abs (mindepth) + Math.Abs (maxdepth);
}
} else { // + / +
depth = maxdepth - mindepth;
}

// Recalculate the vertice points so they start from the correct origin
for (int i=0; i< vertices.Count; i++) {
vertices.X = vertices.X-minwidth;
vertices.Y = vertices.Y-mindepth;
}
#endregion object bounderies

#region create SVG string
string svg = "";
first = true;
foreach (Vertice v in vertices) {
if (first) {
// first starts with "M"
svg += "M" + Math.Round(v.X/width,4).ToString() + "," + Math.Round(v.Y/depth,4).ToString() + " ";
first = false;
} else {
// add L points
svg += "L" + Math.Round(v.X/width,4).ToString() + "," + Math.Round(v.Y/depth,4).ToString() + " ";
}
}
svg += "z"; // z = back to start (M)
#endregion create SVG string

// return the SVG string
return svg;
}
}
}


PHP code:
<?php
include_once "base.php";
if (session_id() == "") { session_start(); }

class SVGCutout {
// private $_exportpath = TMPPATH;
public $lines;

function __construct() {}

// CEILING&WALL cutout
function CreateSVGcutout(): string
{
$vertices = array();
$start = false;
foreach(preg_split("/((\r?\n)|(\r\n?))/", $this->lines) as $line) {
if (str_starts_with($line, 'v ')) {
$start = true;
$parts = preg_split('/\s+/', $line);
// 0 = "v", 1=X, 2=Z, 3=Y
$vertices[] = array($parts[1],$parts[3]);
} else {
if ($start === true) {
// ignore the rest.
break;
}
}
}

// get the object bounderies, I.E. the width and depth of the object
// these are needed to calculate the L points
$minw = 0.0; $maxw = 0.0; $mind = 0.0; $maxd = 0.0;
$first = true;

// get the object boundaries
for ($i = 0; $i < count($vertices); $i++) {
if ($first === true) {
$minw = (float)$vertices[$i][0];
$maxw = (float)$vertices[$i][0];
$mind = (float)$vertices[$i][1];
$maxd = (float)$vertices[$i][1];
$first = false;
} else {
$minw = min($minw, (float)$vertices[$i][0]);
$maxw = max($maxw, (float)$vertices[$i][0]);
$mind = min($mind, (float)$vertices[$i][1]);
$maxd = max($maxd, (float)$vertices[$i][1]);
}
}

// calculate the width and depth
$width = 0.0;
$depth = 0.0;
if ($minw < 0) {
if ($maxw < 0) { $width = abs($minw) - abs($maxw); }
else { $width = abs($minw) + $maxw; }
} else { $width = $maxw - $minw; }
if ($mind < 0) {
if ($maxd < 0) { $depth = abs($mind) - abs($maxd); }
else { $depth = abs($mind) + abs($maxd); }
} else { $depth = $maxd - $mind; }

// to avoid division by zero if either one gets to be 0
if ($width == 0) { return "The width is 0"; }
if ($depth == 0) { return "The depth is 0"; }

// create the svg string
$svg = "";
$first = true;
for ($i = 0; $i < count($vertices); $i++) {
// recalculate the vertice points so they start from the correct origin
$vertices[$i][0] = $vertices[$i][0]-$minw;
$vertices[$i][1] = $vertices[$i][1]-$mind;
// calculate the M and L values
if ($first === true) { $svg .= "M"; $first = false; }
else { $svg .= "L"; }
$svg .= (string)round(($vertices[$i][0])/$width,4) . "," . (string)round(($vertices[$i][1])/$depth,4) . " ";
}
$svg .= "z";

// $fs = fopen($this->_exportpath . "svgoutput.txt", "w");
// fwrite($fs,$svg);
// fclose($fs);

return $svg;
}
}
?>

----------------------------------------
Dodecagon.nl
1300+ 3D models, manuals, and projects

Posted by Xlance at Aug 7, 2026, 10:45:09 AM
Re: Staircase generator plug-in
An excellent solution. Thank You smile
However in many cases I need to get creative and design a cutout which does not correspond to model edges. e.g. circular for a T shaped
----------------------------------------

Windows 64bit | Intel i7 | 8GB Ram | SH3D 7.5 + Plugins

Posted by Keet at Aug 7, 2026, 11:23:05 AM
Re: Staircase generator plug-in
That's why this code solution is easier. You can draw a room in any form you need, for example a star or T and it will calculate the cutout. To be clear: this is independent from the staircase object, completely separate. It is as if you draw the outline as in your examples but now without screenshots and as a room object.
----------------------------------------
Dodecagon.nl
1300+ 3D models, manuals, and projects

Posted by Xlance at Aug 8, 2026, 12:09:39 PM
Re: Staircase generator plug-in

Version 4.2 Released on Sourceforge
(This update took a LOT of time and effort ;-)
Enjoy

https://sourceforge.net/p/sweethome3d/plug-ins/60/#a9db
----------------------------------------

Windows 64bit | Intel i7 | 8GB Ram | SH3D 7.5 + Plugins

Posts: 97   Pages: 10   [ Previous Page | 1 2 3 4 5 6 7 8 9 10 ]