mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 01:41:57 +00:00
Thinking indicator under chat
This commit is contained in:
+4
-1
@@ -110,6 +110,7 @@ const apiKeyLabelEl = $("apiKeyLabel");
|
|||||||
const baseUrlRowEl = $("baseUrlRow");
|
const baseUrlRowEl = $("baseUrlRow");
|
||||||
const baseUrlLabelEl = $("baseUrlLabel");
|
const baseUrlLabelEl = $("baseUrlLabel");
|
||||||
const baseUrlEl = $("baseUrl");
|
const baseUrlEl = $("baseUrl");
|
||||||
|
const thinkingIndicatorEl = $("thinkingIndicator");
|
||||||
const modelEl = $("model");
|
const modelEl = $("model");
|
||||||
const providerEl = $("provider");
|
const providerEl = $("provider");
|
||||||
const ifcFileEl = $("ifcFile");
|
const ifcFileEl = $("ifcFile");
|
||||||
@@ -180,12 +181,14 @@ function addMessage(role, text) {
|
|||||||
wrap.querySelector(".chevron").style.transform = expanded ? '' : 'rotate(90deg)';
|
wrap.querySelector(".chevron").style.transform = expanded ? '' : 'rotate(90deg)';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
msgsEl.appendChild(wrap);
|
msgsEl.insertBefore(wrap, thinkingIndicatorEl);
|
||||||
msgsEl.scrollTop = msgsEl.scrollHeight;
|
msgsEl.scrollTop = msgsEl.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStatus(text) {
|
function setStatus(text) {
|
||||||
statusEl.textContent = text;
|
statusEl.textContent = text;
|
||||||
|
thinkingIndicatorEl.hidden = text !== "Thinking…";
|
||||||
|
msgsEl.scrollTop = msgsEl.scrollHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
const worker = new Worker("./ifc_worker.js", { type: "module" });
|
const worker = new Worker("./ifc_worker.js", { type: "module" });
|
||||||
|
|||||||
@@ -96,7 +96,12 @@
|
|||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="msgs" id="msgs"></div>
|
<div class="msgs" id="msgs">
|
||||||
|
<div class="thinking-indicator" id="thinkingIndicator" hidden>
|
||||||
|
<span class="spinner"></span>
|
||||||
|
<span>thinking...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="composer">
|
<div class="composer">
|
||||||
<div class="inner">
|
<div class="inner">
|
||||||
<textarea id="input" placeholder="Ask or instruct about the IFC model…"></textarea>
|
<textarea id="input" placeholder="Ask or instruct about the IFC model…"></textarea>
|
||||||
|
|||||||
@@ -53,6 +53,23 @@ main {
|
|||||||
margin: 10px 0;
|
margin: 10px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.thinking-indicator {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 10px;
|
||||||
|
color: #555;
|
||||||
|
font-size: 80%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thinking-indicator[hidden] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.thinking-indicator .spinner {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
.msg .role {
|
.msg .role {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
opacity: 0.7;
|
opacity: 0.7;
|
||||||
|
|||||||
@@ -52,6 +52,15 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPointByDistanceExpression* i
|
|||||||
if (inst->OffsetVertical().has_value()) {
|
if (inst->OffsetVertical().has_value()) {
|
||||||
auto offset_vertical = inst->OffsetVertical().get() * length_unit_;
|
auto offset_vertical = inst->OffsetVertical().get() * length_unit_;
|
||||||
o += offset_vertical * z;
|
o += offset_vertical * z;
|
||||||
|
|
||||||
|
auto tmp1 = (z * offset_vertical).eval();
|
||||||
|
auto tmp2 = (Eigen::Vector3d(0, 0, 1) * offset_vertical).eval();
|
||||||
|
auto tmp3 = (tmp1 - tmp2).eval();
|
||||||
|
|
||||||
|
std::ostringstream oss;
|
||||||
|
oss << "local z: " << z.x() << "," << z.y() << "," << z.z() << "; delta: " << tmp3.x() << "," << tmp3.y() << "," << tmp3.z();
|
||||||
|
auto osss = oss.str();
|
||||||
|
std::wcout << osss.c_str() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inst->OffsetLongitudinal().has_value()) {
|
if (inst->OffsetLongitudinal().has_value()) {
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ WHITE = numpy.array((1.0, 1.0, 1.0))
|
|||||||
|
|
||||||
DO_NOTHING = lambda *args: None
|
DO_NOTHING = lambda *args: None
|
||||||
|
|
||||||
|
ARRANGE_POLYGON_SETTINGS = W.arrange_polygon_settings() if hasattr(W, 'arrange_polygon_settings') else None
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class draw_settings:
|
class draw_settings:
|
||||||
@@ -536,7 +537,7 @@ def main(
|
|||||||
*(tup for i, tup in enumerate(zip(path_objects, section_polies, polies)) if has_relevant_zone(i))
|
*(tup for i, tup in enumerate(zip(path_objects, section_polies, polies)) if has_relevant_zone(i))
|
||||||
)
|
)
|
||||||
|
|
||||||
arranged = W.arrange_polygons(polies)
|
arranged = W.arrange_polygons(*filter(None, (ARRANGE_POLYGON_SETTINGS,)), polies)
|
||||||
svg_data_3 = W.polygons_to_svg(arranged, False)
|
svg_data_3 = W.polygons_to_svg(arranged, False)
|
||||||
dom3 = parseString(svg_data_3)
|
dom3 = parseString(svg_data_3)
|
||||||
svg3 = dom3.childNodes[0]
|
svg3 = dom3.childNodes[0]
|
||||||
|
|||||||
@@ -358,6 +358,7 @@ class IFC_PARSE_API entity : public declaration {
|
|||||||
|
|
||||||
const std::vector<const entity*>& subtypes() const { return subtypes_; }
|
const std::vector<const entity*>& subtypes() const { return subtypes_; }
|
||||||
const std::vector<const attribute*>& attributes() const { return attributes_; }
|
const std::vector<const attribute*>& attributes() const { return attributes_; }
|
||||||
|
const std::vector<const inverse_attribute*>& inverse_attributes() const { return inverse_attributes_; }
|
||||||
const std::vector<bool>& derived() const { return derived_; }
|
const std::vector<bool>& derived() const { return derived_; }
|
||||||
|
|
||||||
const std::vector<const attribute*> all_attributes() const {
|
const std::vector<const attribute*> all_attributes() const {
|
||||||
|
|||||||
@@ -1166,6 +1166,7 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
|
|||||||
%ignore svgfill::line_segments_to_polygons;
|
%ignore svgfill::line_segments_to_polygons;
|
||||||
%ignore svgfill::svg_to_polygons;
|
%ignore svgfill::svg_to_polygons;
|
||||||
%ignore svgfill::arrange_polygons;
|
%ignore svgfill::arrange_polygons;
|
||||||
|
%ignore svgfill::abstract_arrangement;
|
||||||
|
|
||||||
%template(svg_line_segments) std::vector<std::array<svgfill::point_2, 2>>;
|
%template(svg_line_segments) std::vector<std::array<svgfill::point_2, 2>>;
|
||||||
%template(svg_groups_of_line_segments) std::vector<std::vector<std::array<svgfill::point_2, 2>>>;
|
%template(svg_groups_of_line_segments) std::vector<std::vector<std::array<svgfill::point_2, 2>>>;
|
||||||
@@ -1287,9 +1288,9 @@ ifcopenshell::geometry::taxonomy::item::ptr try_upcast(PyObject* obj0, swig_type
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<svgfill::polygon_2> arrange_polygons(const std::vector<svgfill::polygon_2>& polygons) {
|
std::vector<svgfill::polygon_2> arrange_polygons(svgfill::arrange_polygon_settings settings, const std::vector<svgfill::polygon_2>& polygons) {
|
||||||
std::vector<svgfill::polygon_2> r;
|
std::vector<svgfill::polygon_2> r;
|
||||||
if (svgfill::arrange_polygons(polygons, r)) {
|
if (svgfill::arrange_polygons(settings, polygons, r)) {
|
||||||
return r;
|
return r;
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error("Failed to arrange polygons");
|
throw std::runtime_error("Failed to arrange polygons");
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -483,6 +483,18 @@ public:
|
|||||||
return ps;
|
return ps;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size_t delete_same_facet_edge_pairs() {
|
||||||
|
size_t n_deleted = 0;
|
||||||
|
for (auto it = arr.edges_begin(); it != arr.edges_end();) {
|
||||||
|
decltype(it) current = it++;
|
||||||
|
if (current->face() == current->twin()->face()) {
|
||||||
|
arr.remove_edge(current);
|
||||||
|
n_deleted++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return n_deleted;
|
||||||
|
}
|
||||||
|
|
||||||
void merge(const std::vector<int>& edge_indices) {
|
void merge(const std::vector<int>& edge_indices) {
|
||||||
if (edge_indices.empty()) {
|
if (edge_indices.empty()) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ namespace svgfill {
|
|||||||
virtual std::vector<int> get_face_pairs() = 0;
|
virtual std::vector<int> get_face_pairs() = 0;
|
||||||
virtual size_t num_edges() = 0;
|
virtual size_t num_edges() = 0;
|
||||||
virtual size_t num_faces() = 0;
|
virtual size_t num_faces() = 0;
|
||||||
|
virtual size_t delete_same_facet_edge_pairs() = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SVGFILL_API context {
|
class SVGFILL_API context {
|
||||||
@@ -101,6 +102,7 @@ namespace svgfill {
|
|||||||
void write(std::vector<std::vector<polygon_2>>&);
|
void write(std::vector<std::vector<polygon_2>>&);
|
||||||
size_t num_edges() { return arr_->num_edges(); }
|
size_t num_edges() { return arr_->num_edges(); }
|
||||||
size_t num_faces() { return arr_->num_faces(); }
|
size_t num_faces() { return arr_->num_faces(); }
|
||||||
|
size_t delete_same_facet_edge_pairs() { return arr_->delete_same_facet_edge_pairs(); }
|
||||||
|
|
||||||
~context() {
|
~context() {
|
||||||
delete arr_;
|
delete arr_;
|
||||||
@@ -113,7 +115,22 @@ namespace svgfill {
|
|||||||
SVGFILL_API std::string polygons_to_svg(const std::vector<std::vector<polygon_2>>& polygons, bool random_color=false);
|
SVGFILL_API std::string polygons_to_svg(const std::vector<std::vector<polygon_2>>& polygons, bool random_color=false);
|
||||||
SVGFILL_API std::string polygons_to_svg(const std::vector<polygon_2>& polygons, bool random_color = false);
|
SVGFILL_API std::string polygons_to_svg(const std::vector<polygon_2>& polygons, bool random_color = false);
|
||||||
SVGFILL_API bool svg_to_polygons(const std::string& data, const boost::optional<std::string>& class_name, std::vector<polygon_2>& polygons);
|
SVGFILL_API bool svg_to_polygons(const std::string& data, const boost::optional<std::string>& class_name, std::vector<polygon_2>& polygons);
|
||||||
SVGFILL_API bool arrange_polygons(const std::vector<polygon_2>& polygons, std::vector<polygon_2>& arranged);
|
|
||||||
}
|
struct SVGFILL_API arrange_polygon_settings {
|
||||||
|
bool debug_output = false;
|
||||||
|
// -1: compute from average edge length
|
||||||
|
double polygon_offset_distance = -1.;
|
||||||
|
// 0: use offset - union - negative offset to find the outer perimeter
|
||||||
|
// 1: radial walk along vertices; exact, but can only reuse vertices, not create new positions by means of intersections
|
||||||
|
int outer_perimiter_algo = 0;
|
||||||
|
// 0: outer perimiter and corridor center lines
|
||||||
|
// 1: input polygons, corridor center lines and segments connecting corridor center lines to input polygons
|
||||||
|
int topology_reconstruction_algo = 0;
|
||||||
|
bool perform_cleanup = true;
|
||||||
|
double subdivision_factor = 16.;
|
||||||
|
};
|
||||||
|
|
||||||
|
SVGFILL_API bool arrange_polygons(arrange_polygon_settings settings, const std::vector<polygon_2>& polygons, std::vector<polygon_2>& arranged);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user