处理多线段、矩形的颜色

master
liaoxianglian 5 months ago
parent 373d6dfa14
commit bbab20d48f

@ -156,6 +156,13 @@ impl TryFrom<&LwPolyline> for Arc {
type Error = String;
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个顶点才能形成圆弧
if lwpolyline.vertices.len() != 2 {
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, // 起始角度(度)
angle: arc_angle, // 圆弧角度跨度(度)
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 {
"line-style:normal;line-weight:thin;filling:none;color:black"
}.into(),
format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb())
},
antialias: false,
})
}

@ -1,5 +1,6 @@
use super::{two_dec, Circularity, ScaleEntity};
use dxf::entities::{self, Circle, LwPolyline, Polyline};
use hex_color::HexColor;
use simple_xml_builder::XMLElement;
#[derive(Debug)]
@ -7,6 +8,7 @@ pub struct Ellipse {
height: f64,
width: f64,
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?
pub x: f64,
@ -22,6 +24,7 @@ impl From<&Circle> for Ellipse {
y: -circ.center.y - circ.radius,
height: 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
//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,
width: ellipse.major_axis.x * 2.0,
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
//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,
height: max_y - y,
width: max_x - x,
color: HexColor::BLACK,
//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?
@ -100,6 +105,12 @@ impl TryFrom<&LwPolyline> for Ellipse {
type Error = &'static str; //add better error later
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();
if !is_bugle_circle&&!poly.is_circular() {
@ -126,6 +137,8 @@ impl TryFrom<&LwPolyline> for Ellipse {
.iter()
.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 {
x,
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
},
width: max_x - x,
color,
//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?
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("antialias", ell.antialias);
ell_xml.add_attribute("style", &ell.style);
ell_xml.add_attribute("color", ell.color.display_rgb().to_string());
ell_xml
}
}
@ -168,6 +183,14 @@ impl Ellipse {
{
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 {

@ -65,6 +65,13 @@ impl TryFrom<&LwPolyline> for Line {
type Error = &'static str; //add better error later
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 {
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?
antialias: false,
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{
"line-style:normal;line-weight:hight;filling:none;color:black"
format!("line-style:normal;line-weight:hight;filling:none;color:{}", color.display_rgb())
} else {
"line-style:normal;line-weight:thin;filling:none;color:black"
}
.into(),
format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb())
},
})
}
}

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

@ -1,5 +1,6 @@
use super::{two_dec, ScaleEntity};
use dxf::entities::{LwPolyline, Polyline, Solid, Spline};
use hex_color::HexColor;
use simple_xml_builder::XMLElement;
use std::ops::{Add, Mul};
@ -79,6 +80,13 @@ impl From<&Polyline> for Polygon {
impl From<&LwPolyline> for Polygon {
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 {
coordinates: poly
.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?
antialias: false,
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 {
"line-style:normal;line-weight:thin;filling:none;color:black"
}
.into(),
format!("line-style:normal;line-weight:thin;filling:none;color:{}", color.display_rgb())
},
}
}
}
@ -311,6 +318,10 @@ pub fn is_rounded_rectangle(lwpolyline: &LwPolyline) -> bool {
/// 将带圆角的四边形拆分为圆弧和直线段
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 vertices = &lwpolyline.vertices;
@ -320,16 +331,16 @@ pub fn decompose_rounded_rectangle(lwpolyline: &LwPolyline) -> Vec<super::Object
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));
}
} else {
// 创建直线段
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 {
"line-style:normal;line-weight:thin;filling:none;color:black"
}.to_string();
format!("line-style:normal;line-weight:thin;filling:none;color:color:{}", color.display_rgb())
};
let line = super::Line::new(
current.x,
@ -346,6 +357,10 @@ pub fn decompose_rounded_rectangle(lwpolyline: &LwPolyline) -> Vec<super::Object
/// 根据bulge值创建圆弧
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 {
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 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(
center_x-radius,

Loading…
Cancel
Save