处理多线段、矩形的颜色

master
liaoxianglian 5 months ago
parent 373d6dfa14
commit bbab20d48f

@ -156,6 +156,13 @@ impl TryFrom<&LwPolyline> for Arc {
type Error = String; type Error = String;
fn try_from(lwpolyline: &LwPolyline) -> Result<Self, Self::Error> { fn try_from(lwpolyline: &LwPolyline) -> Result<Self, Self::Error> {
Self::try_from_lwpolyline_with_color(lwpolyline, HexColor::BLACK)
}
}
impl Arc {
/// 从DXF LwPolyline实体创建Arc支持自定义颜色
pub fn try_from_lwpolyline_with_color(lwpolyline: &LwPolyline, color: HexColor) -> Result<Self, String> {
// 检查顶点数量必须是2个顶点才能形成圆弧 // 检查顶点数量必须是2个顶点才能形成圆弧
if lwpolyline.vertices.len() != 2 { if lwpolyline.vertices.len() != 2 {
return Err(format!("Arc conversion requires exactly 2 vertices, got {}", lwpolyline.vertices.len())); return Err(format!("Arc conversion requires exactly 2 vertices, got {}", lwpolyline.vertices.len()));
@ -239,10 +246,10 @@ impl TryFrom<&LwPolyline> for Arc {
start: start_angle_deg, // 起始角度(度) start: start_angle_deg, // 起始角度(度)
angle: arc_angle, // 圆弧角度跨度(度) angle: arc_angle, // 圆弧角度跨度(度)
style: if lwpolyline.thickness > 0.1 { style: if lwpolyline.thickness > 0.1 {
"line-style:normal;line-weight:normal;filling:none;color:black" format!("line-style:normal;line-weight:normal;filling:none;color:{}", color.display_rgb())
} else { } else {
"line-style:normal;line-weight:thin;filling:none;color:black" format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb())
}.into(), },
antialias: false, antialias: false,
}) })
} }

@ -1,5 +1,6 @@
use super::{two_dec, Circularity, ScaleEntity}; use super::{two_dec, Circularity, ScaleEntity};
use dxf::entities::{self, Circle, LwPolyline, Polyline}; use dxf::entities::{self, Circle, LwPolyline, Polyline};
use hex_color::HexColor;
use simple_xml_builder::XMLElement; use simple_xml_builder::XMLElement;
#[derive(Debug)] #[derive(Debug)]
@ -7,6 +8,7 @@ pub struct Ellipse {
height: f64, height: f64,
width: f64, width: f64,
style: String, style: String,
color: HexColor,
//need to brush up on my Rust scoping rules, isn't there a way to make this pub to just the module? //need to brush up on my Rust scoping rules, isn't there a way to make this pub to just the module?
pub x: f64, pub x: f64,
@ -22,6 +24,7 @@ impl From<&Circle> for Ellipse {
y: -circ.center.y - circ.radius, y: -circ.center.y - circ.radius,
height: circ.radius * 2.0, height: circ.radius * 2.0,
width: circ.radius * 2.0, width: circ.radius * 2.0,
color: HexColor::BLACK,
//in the original code antialias is always set to false...I'm guessing for performance //in the original code antialias is always set to false...I'm guessing for performance
//reasons...I'm trying to think if there is a time we might want to turn it on? //reasons...I'm trying to think if there is a time we might want to turn it on?
@ -43,6 +46,7 @@ impl From<&entities::Ellipse> for Ellipse {
y: -ellipse.center.y - ellipse.major_axis.x * ellipse.minor_axis_ratio, y: -ellipse.center.y - ellipse.major_axis.x * ellipse.minor_axis_ratio,
width: ellipse.major_axis.x * 2.0, width: ellipse.major_axis.x * 2.0,
height: ellipse.major_axis.x * 2.0 * ellipse.minor_axis_ratio, height: ellipse.major_axis.x * 2.0 * ellipse.minor_axis_ratio,
color: HexColor::BLACK,
//in the original code antialias is always set to false...I'm guessing for performance //in the original code antialias is always set to false...I'm guessing for performance
//reasons...I'm trying to think if there is a time we might want to turn it on? //reasons...I'm trying to think if there is a time we might want to turn it on?
@ -87,6 +91,7 @@ impl TryFrom<&Polyline> for Ellipse {
y: -max_y, y: -max_y,
height: max_y - y, height: max_y - y,
width: max_x - x, width: max_x - x,
color: HexColor::BLACK,
//in the original code antialias is always set to false...I'm guessing for performance //in the original code antialias is always set to false...I'm guessing for performance
//reasons...I'm trying to think if there is a time we might want to turn it on? //reasons...I'm trying to think if there is a time we might want to turn it on?
@ -100,6 +105,12 @@ impl TryFrom<&LwPolyline> for Ellipse {
type Error = &'static str; //add better error later type Error = &'static str; //add better error later
fn try_from(poly: &LwPolyline) -> Result<Self, Self::Error> { fn try_from(poly: &LwPolyline) -> Result<Self, Self::Error> {
Self::try_from_lwpolyline_with_color(poly, HexColor::BLACK)
}
}
impl Ellipse {
pub fn try_from_lwpolyline_with_color(poly: &LwPolyline, color: HexColor) -> Result<Self, &'static str> {
let is_bugle_circle = poly.is_circular_with_bulge(); let is_bugle_circle = poly.is_circular_with_bulge();
if !is_bugle_circle&&!poly.is_circular() { if !is_bugle_circle&&!poly.is_circular() {
@ -126,6 +137,8 @@ impl TryFrom<&LwPolyline> for Ellipse {
.iter() .iter()
.fold(f64::MIN, |max_y, vtx| max_y.max(vtx.y)); .fold(f64::MIN, |max_y, vtx| max_y.max(vtx.y));
let style = format!("line-style:normal;line-weight:thin;filling:none;color:rgb({},{},{})", color.r, color.g, color.b);
Ok(Ellipse { Ok(Ellipse {
x, x,
y: if is_bugle_circle {-max_y-(max_x - x)/2.0} else {-max_y}, y: if is_bugle_circle {-max_y-(max_x - x)/2.0} else {-max_y},
@ -135,11 +148,12 @@ impl TryFrom<&LwPolyline> for Ellipse {
max_y - y max_y - y
}, },
width: max_x - x, width: max_x - x,
color,
//in the original code antialias is always set to false...I'm guessing for performance //in the original code antialias is always set to false...I'm guessing for performance
//reasons...I'm trying to think if there is a time we might want to turn it on? //reasons...I'm trying to think if there is a time we might want to turn it on?
antialias: false, antialias: false,
style: "line-style:normal;line-weight:thin;filling:none;color:black".into(), style,
}) })
} }
} }
@ -153,6 +167,7 @@ impl From<&Ellipse> for XMLElement {
ell_xml.add_attribute("height", two_dec(ell.height)); ell_xml.add_attribute("height", two_dec(ell.height));
ell_xml.add_attribute("antialias", ell.antialias); ell_xml.add_attribute("antialias", ell.antialias);
ell_xml.add_attribute("style", &ell.style); ell_xml.add_attribute("style", &ell.style);
ell_xml.add_attribute("color", ell.color.display_rgb().to_string());
ell_xml ell_xml
} }
} }
@ -168,6 +183,14 @@ impl Ellipse {
{ {
update_fn(&mut self.style); update_fn(&mut self.style);
} }
pub fn set_color(&mut self, color: HexColor) {
self.color = color;
}
pub fn get_color(&self) -> HexColor {
self.color
}
} }
impl ScaleEntity for Ellipse { impl ScaleEntity for Ellipse {

@ -65,6 +65,13 @@ impl TryFrom<&LwPolyline> for Line {
type Error = &'static str; //add better error later type Error = &'static str; //add better error later
fn try_from(poly: &LwPolyline) -> Result<Self, Self::Error> { fn try_from(poly: &LwPolyline) -> Result<Self, Self::Error> {
Self::try_from_lwpolyline_with_color(poly, HexColor::BLACK)
}
}
impl Line {
/// 从DXF LwPolyline实体创建Line支持自定义颜色
pub fn try_from_lwpolyline_with_color(poly: &LwPolyline, color: HexColor) -> Result<Self, &'static str> {
if poly.vertices.len() != 2 { if poly.vertices.len() != 2 {
return Err("Error can't convert polyline with more than 2 points into a Line"); return Err("Error can't convert polyline with more than 2 points into a Line");
} }
@ -83,13 +90,12 @@ impl TryFrom<&LwPolyline> for Line {
//reasons...I'm trying to think if there is a time we might want to turn it on? //reasons...I'm trying to think if there is a time we might want to turn it on?
antialias: false, antialias: false,
style: if poly.thickness > 0.1 { style: if poly.thickness > 0.1 {
"line-style:normal;line-weight:normal;filling:none;color:black" format!("line-style:normal;line-weight:normal;filling:none;color:{}", color.display_rgb())
} else if poly.constant_width > 1.0{ } else if poly.constant_width > 1.0{
"line-style:normal;line-weight:hight;filling:none;color:black" format!("line-style:normal;line-weight:hight;filling:none;color:{}", color.display_rgb())
} else { } else {
"line-style:normal;line-weight:thin;filling:none;color:black" format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb())
} },
.into(),
}) })
} }
} }

@ -201,15 +201,16 @@ impl Circularity for LwPolyline {
} }
// 实现Definition的方法 // 实现Definition的方法
// 最后返回文本的definition标签了
impl Definition { impl Definition {
// 创建新的 Definition 实例 // 创建新的 Definition 实例对应elmt的<definition>标签 传入参数:文件名, 步长, dxf图纸
pub fn new(name: impl Into<String>, spline_step: u32, drw: &Drawing) -> Self { pub fn new(name: impl Into<String>, spline_step: u32, drw: &Drawing) -> Self {
/*for st in drw.styles() { /*for st in drw.styles() {
dbg!(st); dbg!(st);
}*/ }*/
// 缩放处理 // 根据制图系统的类型缩放处理
let scale_factor = Self::scale_factor(drw.header.default_drawing_units); let scale_factor = Self::scale_factor(drw.header.default_drawing_units);
// 创建description // 创建description对应elmt的<description>标签,里面就是实际的画图元素标签
let description = { let description = {
let mut description: Description = (drw, spline_step).into(); let mut description: Description = (drw, spline_step).into();
description.scale(scale_factor, scale_factor); description.scale(scale_factor, scale_factor);
@ -847,87 +848,96 @@ impl<'a> ObjectsBuilder<'a> {
} }
} }
}, },
EntityType::LwPolyline(lwpolyline) => match lwpolyline.vertices.len() { EntityType::LwPolyline(lwpolyline) => {
0 | 1 => Err("Error empty LwPolyline"), // 获取颜色
2 => { let color = if let Some(aci_index) = self.ent.common.color.index() {
if lwpolyline.vertices[0].bulge != 0.0 { aci_to_hex_color(aci_index)
match Arc::try_from(lwpolyline) { } else {
Ok(mut arc) => { HexColor::from_u32(self.ent.common.color_24_bit as u32)
arc.update_line_style(&update_line_style); };
arc.scale(self.scale_fact.x, self.scale_fact.y);
arc.x += self.offset.x; match lwpolyline.vertices.len() {
arc.y -= self.offset.y; 0 | 1 => Err("Error empty LwPolyline"),
return Ok(Objects::Arc(arc)); 2 => {
} if lwpolyline.vertices[0].bulge != 0.0 {
Err(_) => { match Arc::try_from_lwpolyline_with_color(lwpolyline, color) {
// Arc转换失败继续执行下面的Line转换 Ok(mut arc) => {
arc.update_line_style(&update_line_style);
arc.scale(self.scale_fact.x, self.scale_fact.y);
arc.x += self.offset.x;
arc.y -= self.offset.y;
return Ok(Objects::Arc(arc));
}
Err(_) => {
// Arc转换失败继续执行下面的Line转换
}
} }
} }
}
let mut line = Line::try_from(lwpolyline)?;
// 根据line_type_name更新线型样式
line.update_line_style(&update_line_style);
line.scale(self.scale_fact.x, self.scale_fact.y); let mut line = Line::try_from_lwpolyline_with_color(lwpolyline, color)?;
line.x1 += self.offset.x;
line.y1 -= self.offset.y;
line.x2 += self.offset.x;
line.y2 -= self.offset.y;
Ok(Objects::Line(line))
}
_ => {
if let Ok(mut ellipse) = Ellipse::try_from(lwpolyline) {
// 根据line_type_name更新线型样式 // 根据line_type_name更新线型样式
ellipse.update_line_style(&update_line_style); line.update_line_style(&update_line_style);
ellipse.scale(self.scale_fact.x, self.scale_fact.y); line.scale(self.scale_fact.x, self.scale_fact.y);
ellipse.x += self.offset.x; line.x1 += self.offset.x;
ellipse.y -= self.offset.y; line.y1 -= self.offset.y;
Ok(Objects::Ellipse(ellipse)) line.x2 += self.offset.x;
} else if polygon::is_rounded_rectangle(lwpolyline) { line.y2 -= self.offset.y;
// 拆分圆角四边形为圆弧和直线段
let mut decomposed_objects = polygon::decompose_rounded_rectangle(lwpolyline); Ok(Objects::Line(line))
}
// 对每个对象应用缩放和偏移 _ => {
for obj in &mut decomposed_objects { if let Ok(mut ellipse) = Ellipse::try_from_lwpolyline_with_color(lwpolyline, color) {
obj.scale(self.scale_fact.x, self.scale_fact.y); // 根据line_type_name更新线型样式
match obj { ellipse.update_line_style(&update_line_style);
Objects::Arc(ref mut arc) => {
arc.x += self.offset.x; ellipse.scale(self.scale_fact.x, self.scale_fact.y);
arc.y -= self.offset.y;
} ellipse.x += self.offset.x;
Objects::Line(ref mut line) => { ellipse.y -= self.offset.y;
line.x1 += self.offset.x;
line.y1 -= self.offset.y; Ok(Objects::Ellipse(ellipse))
line.x2 += self.offset.x; } else if polygon::is_rounded_rectangle(lwpolyline) {
line.y2 -= self.offset.y; // 拆分圆角四边形为圆弧和直线段
let mut decomposed_objects = polygon::decompose_rounded_rectangle_with_color(lwpolyline, color);
// 对每个对象应用缩放和偏移
for obj in &mut decomposed_objects {
obj.scale(self.scale_fact.x, self.scale_fact.y);
match obj {
Objects::Arc(ref mut arc) => {
arc.x += self.offset.x;
arc.y -= self.offset.y;
}
Objects::Line(ref mut line) => {
line.x1 += self.offset.x;
line.y1 -= self.offset.y;
line.x2 += self.offset.x;
line.y2 -= self.offset.y;
}
_ => {}
} }
_ => {}
} }
}
Ok(Objects::Group(decomposed_objects))
Ok(Objects::Group(decomposed_objects)) } else {
} else { let mut poly: Polygon = Polygon::from_lwpolyline_with_color(lwpolyline, color);
let mut poly: Polygon = lwpolyline.into();
// 根据line_type_name更新线型样式 // 根据line_type_name更新线型样式
poly.update_line_style(&update_line_style); poly.update_line_style(&update_line_style);
poly.scale(self.scale_fact.x, self.scale_fact.y); poly.scale(self.scale_fact.x, self.scale_fact.y);
for cord in &mut poly.coordinates { for cord in &mut poly.coordinates {
cord.x += self.offset.x; cord.x += self.offset.x;
cord.y -= self.offset.y; cord.y -= self.offset.y;
} }
Ok(Objects::Polygon(poly)) Ok(Objects::Polygon(poly))
}
} }
} }
}, },

@ -1,5 +1,6 @@
use super::{two_dec, ScaleEntity}; use super::{two_dec, ScaleEntity};
use dxf::entities::{LwPolyline, Polyline, Solid, Spline}; use dxf::entities::{LwPolyline, Polyline, Solid, Spline};
use hex_color::HexColor;
use simple_xml_builder::XMLElement; use simple_xml_builder::XMLElement;
use std::ops::{Add, Mul}; use std::ops::{Add, Mul};
@ -79,6 +80,13 @@ impl From<&Polyline> for Polygon {
impl From<&LwPolyline> for Polygon { impl From<&LwPolyline> for Polygon {
fn from(poly: &LwPolyline) -> Self { fn from(poly: &LwPolyline) -> Self {
Self::from_lwpolyline_with_color(poly, HexColor::BLACK)
}
}
impl Polygon {
/// 从DXF LwPolyline实体创建Polygon支持自定义颜色
pub fn from_lwpolyline_with_color(poly: &LwPolyline, color: HexColor) -> Self {
Polygon { Polygon {
coordinates: poly coordinates: poly
.vertices .vertices
@ -93,11 +101,10 @@ impl From<&LwPolyline> for Polygon {
//reasons...I'm trying to think if there is a time we might want to turn it on? //reasons...I'm trying to think if there is a time we might want to turn it on?
antialias: false, antialias: false,
style: if poly.thickness > 0.1 { style: if poly.thickness > 0.1 {
"line-style:normal;line-weight:normal;filling:none;color:black" format!("line-style:normal;line-weight:normal;filling:none;color:{}", color.display_rgb())
} else { } else {
"line-style:normal;line-weight:thin;filling:none;color:black" format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb())
} },
.into(),
} }
} }
} }
@ -311,6 +318,10 @@ pub fn is_rounded_rectangle(lwpolyline: &LwPolyline) -> bool {
/// 将带圆角的四边形拆分为圆弧和直线段 /// 将带圆角的四边形拆分为圆弧和直线段
pub fn decompose_rounded_rectangle(lwpolyline: &LwPolyline) -> Vec<super::Objects> { pub fn decompose_rounded_rectangle(lwpolyline: &LwPolyline) -> Vec<super::Objects> {
decompose_rounded_rectangle_with_color(lwpolyline, HexColor::BLACK)
}
pub fn decompose_rounded_rectangle_with_color(lwpolyline: &LwPolyline, color: HexColor) -> Vec<super::Objects> {
let mut objects = Vec::new(); let mut objects = Vec::new();
let vertices = &lwpolyline.vertices; let vertices = &lwpolyline.vertices;
@ -320,16 +331,16 @@ pub fn decompose_rounded_rectangle(lwpolyline: &LwPolyline) -> Vec<super::Object
if current.bulge.abs() > 1e-10 { if current.bulge.abs() > 1e-10 {
// 创建圆弧段 // 创建圆弧段
if let Some(arc) = create_arc_from_bulge(current.x, current.y, next.x, next.y, current.bulge) { if let Some(arc) = create_arc_from_bulge_with_color(current.x, current.y, next.x, next.y, current.bulge, color) {
objects.push(super::Objects::Arc(arc)); objects.push(super::Objects::Arc(arc));
} }
} else { } else {
// 创建直线段 // 创建直线段
let style = if lwpolyline.thickness > 0.5 { let style = if lwpolyline.thickness > 0.5 {
"line-style:normal;line-weight:normal;filling:none;color:black" format!("line-style:normal;line-weight:normal;filling:none;color:color:{}", color.display_rgb())
} else { } else {
"line-style:normal;line-weight:thin;filling:none;color:black" format!("line-style:normal;line-weight:thin;filling:none;color:color:{}", color.display_rgb())
}.to_string(); };
let line = super::Line::new( let line = super::Line::new(
current.x, current.x,
@ -346,6 +357,10 @@ pub fn decompose_rounded_rectangle(lwpolyline: &LwPolyline) -> Vec<super::Object
/// 根据bulge值创建圆弧 /// 根据bulge值创建圆弧
fn create_arc_from_bulge(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bulge: f64) -> Option<super::Arc> { fn create_arc_from_bulge(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bulge: f64) -> Option<super::Arc> {
create_arc_from_bulge_with_color(start_x, start_y, end_x, end_y, bulge, HexColor::BLACK)
}
fn create_arc_from_bulge_with_color(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bulge: f64, color: HexColor) -> Option<super::Arc> {
if bulge.abs() <= 1e-10 { if bulge.abs() <= 1e-10 {
return None; return None;
} }
@ -442,7 +457,7 @@ fn create_arc_from_bulge(start_x: f64, start_y: f64, end_x: f64, end_y: f64, bul
// let start_angle = (start_y - center_y).atan2(start_x - center_x).to_degrees(); // let start_angle = (start_y - center_y).atan2(start_x - center_x).to_degrees();
// let angle_span = angle.to_degrees().abs(); // let angle_span = angle.to_degrees().abs();
let style = "line-style:normal;line-weight:thin;filling:none;color:black".to_string(); let style = format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb());
Some(super::Arc::new( Some(super::Arc::new(
center_x-radius, center_x-radius,

Loading…
Cancel
Save