forked from 1b-agent/opencadstudio-upstream
Bundle the first-party Python scripting plugin
This commit is contained in:
1 parent
889042c1f1
commit
de51c1a17f
26 files changed
+11459
-27
No files matched your search
@@ -0,0 +1,54 @@
|
||||
//! Create one disposable DWG with a paper layout and rectangular viewport.
|
||||
//! Usage: cargo run --example create_layout_fixture -- /absolute/output.dwg
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
use ocs_plugin_api::host::acadrust::{
|
||||
entities::{Line, Text, Viewport},
|
||||
CadDocument, DwgWriter, EntityType, Vector3,
|
||||
};
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let output = std::env::args().nth(1).ok_or("expected output DWG path")?;
|
||||
let output = std::path::PathBuf::from(output);
|
||||
let twisted = std::env::args().nth(2).as_deref() == Some("--twisted");
|
||||
if output.extension().is_none_or(|value| value != "dwg")
|
||||
|| output.parent().is_none_or(|parent| !parent.is_dir())
|
||||
{
|
||||
return Err("output must be a .dwg in an existing directory".into());
|
||||
}
|
||||
let mut document = CadDocument::new();
|
||||
document.add_layout("Sheet")?;
|
||||
document.add_entity(EntityType::Line(Line::from_coords(
|
||||
-50.0, 0.0, 0.0, 50.0, 0.0, 0.0,
|
||||
)))?;
|
||||
document.add_entity_to_layout(
|
||||
EntityType::Text(Text::with_value(
|
||||
"Sheet note",
|
||||
Vector3::new(20.0, 20.0, 0.0),
|
||||
)),
|
||||
"Sheet",
|
||||
)?;
|
||||
let mut viewport = Viewport::new();
|
||||
viewport.id = 2;
|
||||
viewport.center = Vector3::new(100.0, 80.0, 0.0);
|
||||
viewport.width = 100.0;
|
||||
viewport.height = 50.0;
|
||||
viewport.view_height = 100.0;
|
||||
viewport.view_center = Vector3::new(10.0, 20.0, 0.0);
|
||||
viewport.view_target = Vector3::ZERO;
|
||||
if twisted {
|
||||
viewport.twist_angle = std::f64::consts::FRAC_PI_2;
|
||||
viewport.view_target = Vector3::new(5.0, 10.0, 0.0);
|
||||
}
|
||||
document.add_entity_to_layout(EntityType::Viewport(viewport), "Sheet")?;
|
||||
|
||||
let mut file = std::fs::OpenOptions::new()
|
||||
.write(true)
|
||||
.create_new(true)
|
||||
.open(&output)?;
|
||||
DwgWriter::write_to_writer(&mut file, &document)?;
|
||||
file.flush()?;
|
||||
println!("Created {}", output.display());
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
# Example script for opencad-python's PY_RUN command.
|
||||
#
|
||||
# Historical experimental command-replay example. The portable default
|
||||
# build omits ocs.command()/ocs.select(); nested replay may hang in OCS 2026.37.
|
||||
#
|
||||
# Draws two rectangles, a triangle, an arc, a pair of lines made parallel by
|
||||
# a real PCONSTRAINT, a circle made tangent to a line by a real TCONSTRAINT,
|
||||
# and a row of points added in one ocs.add_points() batch call, one of which
|
||||
# gets an XDATA record written, read back, and removed. Every ocs.add_*/
|
||||
# ocs.write_record call in one PY_RUN shares a script undo group. Command
|
||||
# replay has separate host undo semantics.
|
||||
#
|
||||
# These ARE real, persistent constraint objects, not just geometrically
|
||||
# correct-looking shapes: drag one of the two "parallel" lines afterward and
|
||||
# the other follows to stay parallel, same for the tangent circle. Verified
|
||||
# end-to-end (not just "it compiles"): after ocs.command("PCONSTRAINT") /
|
||||
# ("TCONSTRAINT"), the geometry visibly changes and satisfies the
|
||||
# relationship exactly (checked numerically — direction-vector cross
|
||||
# product ~0 for parallel, center-to-line distance == radius for tangent).
|
||||
#
|
||||
# ocs.select(handles) + ocs.command(name) is what makes this possible:
|
||||
# constraint commands read a prior *selection* (a "Select objects:"
|
||||
# prompt), not picks fed as command-line tokens the way LINE's points are —
|
||||
# select the entities first, then run the bare command name. See PLUGIN.md
|
||||
# for the two host-side additions (HostApi::run_command / set_selection)
|
||||
# this needed and exactly what they do and don't cover.
|
||||
|
||||
if not hasattr(ocs, "command") or not hasattr(ocs, "select"):
|
||||
raise RuntimeError("This example requires experimental command replay host APIs")
|
||||
|
||||
def rectangle(x, y, w, h):
|
||||
l1 = ocs.add_line(x, y, x + w, y)
|
||||
l2 = ocs.add_line(x + w, y, x + w, y + h)
|
||||
l3 = ocs.add_line(x + w, y + h, x, y + h)
|
||||
l4 = ocs.add_line(x, y + h, x, y)
|
||||
return [l1, l2, l3, l4]
|
||||
|
||||
# ── Two rectangles (not aligned to each other — see the note below) ───────
|
||||
rectangle(0, 0, 20, 10)
|
||||
rectangle(30, 2, 18, 9)
|
||||
|
||||
# ── A triangle (three lines closing a loop) ────────────────────────────────
|
||||
ocs.add_line(60, 0, 75, 0)
|
||||
ocs.add_line(75, 0, 67.5, 12)
|
||||
ocs.add_line(67.5, 12, 60, 0)
|
||||
|
||||
# ── An arc, for variety ─────────────────────────────────────────────────────
|
||||
ocs.add_arc(67.5, 20, 8, 0, 180)
|
||||
|
||||
# ── Two lines, deliberately NOT parallel — then made parallel by a real ───
|
||||
# ── persistent PCONSTRAINT (not just recomputed coordinates).
|
||||
line_a = ocs.add_line(0, 20, 20, 24)
|
||||
line_b = ocs.add_line(0, 30, 20, 33)
|
||||
ocs.select([line_a, line_b])
|
||||
ocs.command("PCONSTRAINT")
|
||||
|
||||
# ── A line and a circle, deliberately NOT touching — then made tangent by ──
|
||||
# ── a real persistent TCONSTRAINT.
|
||||
tangent_line = ocs.add_line(0, 40, 20, 40)
|
||||
tangent_circle = ocs.add_circle(10, 44, 3)
|
||||
ocs.select([tangent_line, tangent_circle])
|
||||
ocs.command("TCONSTRAINT")
|
||||
|
||||
# ── What's NOT in this script: aligning the two rectangles to each other ──
|
||||
# ── (a real ALIGN, not just matching coordinates). Tried it separately:
|
||||
# ── ocs.command("ALIGN <points...>") DOES apply the transform correctly,
|
||||
# ── but ALIGN asks a trailing "Scale objects? [Yes/No]" question that
|
||||
# ── ocs.command()'s point-feeding doesn't answer (it sends exactly one
|
||||
# ── trailing Enter, and ALIGN needs two — one to skip the optional 3rd
|
||||
# ── point pair, one for the scale question) — it leaves that prompt open
|
||||
# ── instead of cleanly finishing. Left out of this script rather than
|
||||
# ── shipping something that half-works; see PLUGIN.md for the detail.
|
||||
|
||||
# ── A batch of points, added in one HostApi::add_entities() call instead ──
|
||||
# ── of one ocs.add_line-style call per point.
|
||||
point_handles = ocs.add_points([[x, 50, 0] for x in range(0, 21, 2)])
|
||||
|
||||
# ── Tag one of those points with an XDATA record, read it back, then ───────
|
||||
# ── remove it — round-tripping every supported value kind.
|
||||
tagged = point_handles[0]
|
||||
ocs.write_record(tagged, "OPENCAD_EXAMPLE", [
|
||||
{"kind": "String", "value": "origin marker"},
|
||||
{"kind": "Point3D", "value": [0.0, 50.0, 0.0]},
|
||||
{"kind": "Integer32", "value": 1},
|
||||
])
|
||||
record = ocs.read_record(tagged, "OPENCAD_EXAMPLE")
|
||||
assert record["app_name"] == "OPENCAD_EXAMPLE"
|
||||
assert record["values"][0] == {"kind": "String", "value": "origin marker"}
|
||||
ocs.remove_record(tagged, "OPENCAD_EXAMPLE")
|
||||
assert ocs.read_record(tagged, "OPENCAD_EXAMPLE") is None
|
||||
Reference in new issue
Block a user