Fix to have deterministic order of commands (#5583)
This commit is contained in:
@ -5,6 +5,7 @@ use derive_docs::stdlib;
|
|||||||
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::CutType, ModelingCmd};
|
use kcmc::{each_cmd as mcmd, length_unit::LengthUnit, shared::CutType, ModelingCmd};
|
||||||
use kittycad_modeling_cmds as kcmc;
|
use kittycad_modeling_cmds as kcmc;
|
||||||
|
|
||||||
|
use super::utils::unique_count;
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, Solid},
|
execution::{ChamferSurface, EdgeCut, ExecState, ExtrudeSurface, GeoMeta, KclValue, Solid},
|
||||||
@ -109,10 +110,8 @@ async fn inner_chamfer(
|
|||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<Solid>, KclError> {
|
) -> Result<Box<Solid>, KclError> {
|
||||||
// Check if tags contains any duplicate values.
|
// Check if tags contains any duplicate values.
|
||||||
let mut tags = tags.clone();
|
let unique_tags = unique_count(tags.clone());
|
||||||
tags.sort();
|
if unique_tags != tags.len() {
|
||||||
tags.dedup();
|
|
||||||
if tags.len() != tags.len() {
|
|
||||||
return Err(KclError::Type(KclErrorDetails {
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
message: "Duplicate tags are not allowed.".to_string(),
|
message: "Duplicate tags are not allowed.".to_string(),
|
||||||
source_ranges: vec![args.source_range],
|
source_ranges: vec![args.source_range],
|
||||||
|
@ -11,6 +11,7 @@ use schemars::JsonSchema;
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
use super::utils::unique_count;
|
||||||
use crate::{
|
use crate::{
|
||||||
errors::{KclError, KclErrorDetails},
|
errors::{KclError, KclErrorDetails},
|
||||||
execution::{EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, Solid, TagIdentifier},
|
execution::{EdgeCut, ExecState, ExtrudeSurface, FilletSurface, GeoMeta, KclValue, Solid, TagIdentifier},
|
||||||
@ -20,7 +21,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// A tag or a uuid of an edge.
|
/// A tag or a uuid of an edge.
|
||||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq, Ord, PartialOrd, Hash)]
|
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, ts_rs::TS, JsonSchema, Eq, Hash)]
|
||||||
#[ts(export)]
|
#[ts(export)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
pub enum EdgeReference {
|
pub enum EdgeReference {
|
||||||
@ -129,10 +130,8 @@ async fn inner_fillet(
|
|||||||
args: Args,
|
args: Args,
|
||||||
) -> Result<Box<Solid>, KclError> {
|
) -> Result<Box<Solid>, KclError> {
|
||||||
// Check if tags contains any duplicate values.
|
// Check if tags contains any duplicate values.
|
||||||
let mut unique_tags = tags.clone();
|
let unique_tags = unique_count(tags.clone());
|
||||||
unique_tags.sort();
|
if unique_tags != tags.len() {
|
||||||
unique_tags.dedup();
|
|
||||||
if unique_tags.len() != tags.len() {
|
|
||||||
return Err(KclError::Type(KclErrorDetails {
|
return Err(KclError::Type(KclErrorDetails {
|
||||||
message: "Duplicate tags are not allowed.".to_string(),
|
message: "Duplicate tags are not allowed.".to_string(),
|
||||||
source_ranges: vec![args.source_range],
|
source_ranges: vec![args.source_range],
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use std::f64::consts::PI;
|
use std::{collections::HashSet, f64::consts::PI};
|
||||||
|
|
||||||
use kittycad_modeling_cmds::shared::Angle;
|
use kittycad_modeling_cmds::shared::Angle;
|
||||||
|
|
||||||
@ -8,6 +8,16 @@ use crate::{
|
|||||||
source_range::SourceRange,
|
source_range::SourceRange,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Count the number of unique items in a `Vec` in O(n) time.
|
||||||
|
pub(crate) fn unique_count<T: Eq + std::hash::Hash>(vec: Vec<T>) -> usize {
|
||||||
|
// Add to a set.
|
||||||
|
let mut set = HashSet::with_capacity(vec.len());
|
||||||
|
for item in vec {
|
||||||
|
set.insert(item);
|
||||||
|
}
|
||||||
|
set.len()
|
||||||
|
}
|
||||||
|
|
||||||
/// Get the distance between two points.
|
/// Get the distance between two points.
|
||||||
pub fn distance(a: Point2d, b: Point2d) -> f64 {
|
pub fn distance(a: Point2d, b: Point2d) -> f64 {
|
||||||
((b.x - a.x).powi(2) + (b.y - a.y).powi(2)).sqrt()
|
((b.x - a.x).powi(2) + (b.y - a.y).powi(2)).sqrt()
|
||||||
@ -676,6 +686,11 @@ mod get_tangential_arc_to_info_tests {
|
|||||||
(num * 1000.0).round() / 1000.0
|
(num * 1000.0).round() / 1000.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_unique_count() {
|
||||||
|
assert_eq!(unique_count(vec![1, 2, 2, 3, 2]), 3);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic_case() {
|
fn test_basic_case() {
|
||||||
let result = get_tangential_arc_to_info(TangentialArcInfoInput {
|
let result = get_tangential_arc_to_info(TangentialArcInfoInput {
|
||||||
|
Reference in New Issue
Block a user