makepad_platform/
draw_vars.rs

1use {
2    crate::{
3        makepad_live_compiler::{
4            LiveRegistry,
5            TokenSpan,
6            LivePtr,
7            LiveValue,
8            LiveTypeInfo,
9            LiveFieldKind,
10            LiveModuleId,
11            LiveType,
12            LiveId,
13            LiveNode,
14            LiveNodeSliceApi
15        },
16        makepad_live_tokenizer::{LiveErrorOrigin, live_error_origin},
17        makepad_shader_compiler::*,
18        makepad_live_id::*,
19        makepad_math::*,
20        cx::Cx,
21        texture::{Texture, TextureId},
22        makepad_error_log::*,
23        geometry::GeometryId,
24        area::Area,
25        geometry::{GeometryFields},
26        live_traits::*,
27        draw_shader::*
28    },
29};
30
31/*
32pub enum ShaderCompileResult {
33    Nop,
34    Ok
35}*/
36
37
38#[cfg(any(target_arch = "wasm32", target_os="android", target_os="linux"))]
39pub const fn shader_enum(i: u32) -> u32 {
40    match i {
41        1 => 0x3f800000,
42        2 => 0x40000000,
43        3 => 0x40400000,
44        4 => 0x40800000,
45        5 => 0x40a00000,
46        6 => 0x40c00000,
47        7 => 0x40e00000,
48        8 => 0x41000000,
49        9 => 0x41100000,
50        10 => 0x41200000,
51        11 => 0x41300000,
52        12 => 0x41400000,
53        13 => 0x41500000,
54        14 => 0x41600000,
55        15 => 0x41700000,
56        16 => 0x41800000,
57        17 => 0x41880000,
58        18 => 0x41900000,
59        19 => 0x41980000,
60        20 => 0x41a00000,
61        21 => 0x41a80000,
62        22 => 0x41b00000,
63        23 => 0x41b80000,
64        24 => 0x41c00000,
65        25 => 0x41c80000,
66        26 => 0x41d00000,
67        27 => 0x41d80000,
68        28 => 0x41e00000,
69        29 => 0x41e80000,
70        30 => 0x41f00000,
71        31 => 0x41f80000,
72        _ => panic!()
73    }
74}
75
76#[cfg(not(any(target_arch = "wasm32", target_os="android", target_os="linux")))]
77pub const fn shader_enum(i: u32) -> u32 {
78    if i<1 || i > 31 {
79        panic!();
80    }
81    i
82}
83
84pub const DRAW_CALL_USER_UNIFORMS: usize = 16;
85pub const DRAW_CALL_TEXTURE_SLOTS: usize = 4;
86pub const DRAW_CALL_VAR_INSTANCES: usize = 32;
87
88#[derive(Default, Debug)]
89#[repr(C)]
90pub struct DrawVars {
91    pub area: Area,
92    pub (crate) var_instance_start: usize,
93    pub (crate) var_instance_slots: usize,
94    pub (crate) options: CxDrawShaderOptions,
95    pub draw_shader: Option<DrawShader>,
96    pub (crate) geometry_id: Option<GeometryId>,
97    pub user_uniforms: [f32; DRAW_CALL_USER_UNIFORMS],
98    pub texture_slots: [Option<TextureId>; DRAW_CALL_TEXTURE_SLOTS],
99    pub var_instances: [f32; DRAW_CALL_VAR_INSTANCES]
100}
101
102impl LiveHookDeref for DrawVars{}
103
104impl LiveNew for DrawVars {
105    fn new(_cx: &mut Cx) -> Self {
106        Self::default()
107    }
108    
109    fn live_type_info(_cx: &mut Cx) -> LiveTypeInfo {
110        LiveTypeInfo {
111            module_id: LiveModuleId::from_str(&module_path!()).unwrap(),
112            live_type: std::any::TypeId::of::<Self>(),
113            live_ignore: true,
114            fields: Vec::new(),
115            type_name: id_lut!(DrawVars)
116        }
117    }
118}
119
120impl LiveApply for DrawVars {
121    fn apply(&mut self, _cx: &mut Cx, _from: ApplyFrom, _index: usize, _nodes: &[LiveNode]) -> usize {
122        panic!()
123    }
124}
125
126impl LiveHook for DrawVars {}
127
128impl DrawVars {
129    
130    pub fn set_texture(&mut self, slot: usize, texture: &Texture) {
131        self.texture_slots[slot] = Some(texture.texture_id());
132    }
133    
134    pub fn empty_texture(&mut self, slot: usize) {
135        self.texture_slots[slot] = None;
136    }
137
138    pub fn redraw(&self, cx: &mut Cx) {
139        self.area.redraw(cx);
140    }
141    
142    pub fn area(&self) -> Area {
143        self.area
144    }
145    
146    pub fn can_instance(&self) -> bool {
147        self.draw_shader.is_some()
148    }
149    
150    pub fn as_slice<'a>(&'a self) -> &'a [f32] {
151        unsafe {
152            std::slice::from_raw_parts((&self.var_instances[self.var_instance_start - 1] as *const _ as *const f32).offset(1), self.var_instance_slots)
153        }
154    }
155    
156    pub fn init_shader(&mut self, cx: &mut Cx, from: ApplyFrom, draw_shader_ptr: DrawShaderPtr, geometry_fields: &dyn GeometryFields) {
157        self.draw_shader = None;
158        
159        if cx.draw_shaders.error_set.contains(&draw_shader_ptr) {
160            return
161        }
162        
163        if let Some(item) = cx.draw_shaders.ptr_to_item.get(&draw_shader_ptr) {
164            self.draw_shader = Some(DrawShader {
165                draw_shader_generation: cx.draw_shaders.generation,
166                draw_shader_ptr,
167                draw_shader_id: item.draw_shader_id
168            });
169            self.options = item.options.clone();
170        }
171        else {
172            // create a fingerprint from all the dsl nodes only
173            let fingerprint = DrawShaderFingerprint::from_ptr(cx, draw_shader_ptr);
174            
175            // see if we have it already
176            if let Some(fp) = cx.draw_shaders.fingerprints.iter().find( | fp | fp.fingerprint == fingerprint) {
177                self.options = CxDrawShaderOptions::from_ptr(cx, draw_shader_ptr);
178                cx.draw_shaders.ptr_to_item.insert(draw_shader_ptr, CxDrawShaderItem {
179                    draw_shader_id: fp.draw_shader_id,
180                    options: self.options.clone()
181                });
182                self.draw_shader = Some(DrawShader {
183                    draw_shader_generation: cx.draw_shaders.generation,
184                    draw_shader_ptr,
185                    draw_shader_id: fp.draw_shader_id
186                });
187                return;
188            }
189            
190            // see if another variant errored
191            if cx.draw_shaders.error_fingerprints.iter().find( | fp | **fp == fingerprint).is_some() {
192                return;
193            }
194
195            fn live_type_to_shader_ty(live_type: LiveType) -> Option<ShaderTy> {
196                if live_type == LiveType::of::<f32>() {Some(ShaderTy::Float)}
197                else if live_type == LiveType::of::<Vec2>() {Some(ShaderTy::Vec2)}
198                else if live_type == LiveType::of::<Vec3>() {Some(ShaderTy::Vec3)}
199                else if live_type == LiveType::of::<Vec4>() {Some(ShaderTy::Vec4)}
200                else {None}
201            }
202            // ok ! we have to compile it
203            //let live_factories = &cx.live_factories;
204            let live_registry_cp = cx.live_registry.clone();
205            let live_registry = live_registry_cp.borrow();
206            
207            let result = cx.shader_registry.analyse_draw_shader(&live_registry, draw_shader_ptr, | live_registry, shader_registry, span, draw_shader_query, live_type, draw_shader_def | {
208                match draw_shader_query {
209                    DrawShaderQuery::DrawShader => {
210                        fn recur_expand(
211                            live_registry: &LiveRegistry,
212                            shader_registry: &ShaderRegistry,
213                            level: usize,
214                            after_draw_vars: &mut bool,
215                            live_type: LiveType,
216                            draw_shader_def: &mut DrawShaderDef,
217                            span: TokenSpan
218                        ) {
219                            if let Some(lf) = live_registry.live_type_infos.get(&live_type) {
220                                
221                                let mut slots = 0;
222                                for field in &lf.fields {
223                                    if let LiveFieldKind::Deref = field.live_field_kind {
224                                        if field.live_type_info.live_type != LiveType::of::<DrawVars>() {
225                                            recur_expand(live_registry, shader_registry, level + 1, after_draw_vars, field.live_type_info.live_type, draw_shader_def, span);
226                                            continue
227                                        }
228                                        else{
229                                            *after_draw_vars = true;
230                                            continue
231                                        }
232                                    }
233                                    if *after_draw_vars {
234                                        // lets count sizes
235                                        //
236                                        let live_type = field.live_type_info.live_type;
237                                        if shader_registry.enums.get(&live_type).is_some() {
238                                            slots += 1;
239                                            //draw_shader_def.enums
240                                            
241                                            draw_shader_def.add_instance(field.id, ShaderTy::Enum(live_type), span, field.live_field_kind);
242                                        }
243                                        else {
244                                            let ty = live_type_to_shader_ty(live_type).expect("Please only put shader-understandable instance fields after draw_vars");
245                                            slots += ty.slots();
246                                            draw_shader_def.add_instance(field.id, ty, span, field.live_field_kind);
247                                        }
248                                    }
249                                }
250                                // insert padding
251                                if level >0 && slots % 2 == 1 {
252                                    draw_shader_def.add_instance(LiveId(0), ShaderTy::Float, span, LiveFieldKind::Calc);
253                                }
254                            }
255                        }
256                        recur_expand(live_registry, shader_registry, 0, &mut false, live_type, draw_shader_def, span);
257                    }
258                    DrawShaderQuery::Geometry => {
259                        if live_type == geometry_fields.live_type_check() {
260                            let mut fields = Vec::new();
261                            geometry_fields.geometry_fields(&mut fields);
262                            for field in fields {
263                                draw_shader_def.add_geometry(field.id, field.ty, span);
264                            }
265                        }
266                        else {
267                            eprintln!("lf.get_type() != geometry_fields.live_type_check()");
268                        }
269                    }
270                }
271            });
272            // ok lets print an error
273            match result {
274                Err(e) => {
275                    cx.draw_shaders.error_set.insert(draw_shader_ptr);
276                    cx.draw_shaders.error_fingerprints.push(fingerprint);
277                    // ok so. lets get the source for this file id
278                    let err = live_registry.live_error_to_live_file_error(e);
279                    if std::env::args().find(|v| v == "--message-format=json").is_some(){
280                        crate::makepad_error_log::log_with_type(
281                            &err.file,
282                            err.span.start.line+1,
283                            err.span.start.column+2,
284                            err.span.end.line+1,
285                            err.span.end.column+2,
286                            &err.message,
287                            LogType::Error
288                        );
289                    }
290                    else{
291                        log!("Error {}", err);
292                    }
293                }
294                Ok(()) => {
295                    // OK! SO the shader parsed
296                    let draw_shader_id = cx.draw_shaders.shaders.len();
297                    
298                    //let const_table = DrawShaderConstTable::default();
299                    let const_table = cx.shader_registry.compute_const_table(draw_shader_ptr);
300                    
301                    let mut mapping = CxDrawShaderMapping::from_draw_shader_def(
302                        cx.shader_registry.draw_shader_defs.get(&draw_shader_ptr).unwrap(),
303                        const_table,
304                        DRAW_SHADER_INPUT_PACKING
305                    );
306                    
307                    mapping.update_live_and_user_uniforms(cx, from);
308                    
309                    let live_registry_rc = cx.live_registry.clone();
310                    let live_registry = live_registry_rc.borrow();
311                    let class_node = live_registry.ptr_to_node(draw_shader_ptr.0);
312                    
313                    let shader_type_name = match &class_node.value {
314                        LiveValue::Class {live_type, ..} => {
315                            // lets get the type name
316                            let lti = live_registry.live_type_infos.get(live_type).unwrap();
317                            lti.type_name
318                        }
319                        _ => LiveId(0)
320                    };
321                    cx.draw_shaders.fingerprints.push(DrawShaderFingerprint {
322                        draw_shader_id,
323                        fingerprint
324                    });
325                    cx.draw_shaders.shaders.push(CxDrawShader {
326                        class_prop: class_node.id,
327                        type_name: shader_type_name,
328                        os_shader_id: None,
329                        mapping: mapping
330                    });
331                    // ok so. maybe we should fill the live_uniforms buffer?
332                    self.options = CxDrawShaderOptions::from_ptr(cx, draw_shader_ptr);
333                    cx.draw_shaders.ptr_to_item.insert(draw_shader_ptr, CxDrawShaderItem {
334                        draw_shader_id,
335                        options: self.options.clone()
336                    });
337                    cx.draw_shaders.compile_set.insert(draw_shader_ptr);
338                    // now we simply queue it somewhere somehow to compile.
339                    self.draw_shader = Some(DrawShader {
340                        draw_shader_generation: cx.draw_shaders.generation,
341                        draw_shader_id,
342                        draw_shader_ptr
343                    });
344                    
345                    // self.geometry_id = geometry_fields.get_geometry_id();
346                    //println!("{:?}", self.geometry_id);
347                    // also we should allocate it a Shader object
348                }
349            }
350        }
351    }
352    
353    pub fn update_area_with_self(&mut self, cx: &mut Cx, index: usize, nodes: &[LiveNode]) {
354        if let Some(draw_shader) = self.draw_shader {
355            if let Some(inst) = self.area.valid_instance(cx) {
356                if draw_shader.draw_shader_generation != cx.draw_shaders.generation {
357                    return;
358                }
359                let sh = &cx.draw_shaders[draw_shader.draw_shader_id];
360                let draw_list = &mut cx.draw_lists[inst.draw_list_id];
361                let draw_item = &mut draw_list.draw_items[inst.draw_item_id];
362                let draw_call = draw_item.kind.draw_call_mut().unwrap();
363                
364                let repeat = inst.instance_count;
365                let stride = sh.mapping.instances.total_slots;
366                let instances = &mut draw_item.instances.as_mut().unwrap()[inst.instance_offset..];
367                let inst_slice = self.as_slice();
368                
369                let mut node_iter = nodes.first_child(index);
370                while let Some(node_index) = node_iter {
371                    let id = nodes[node_index].id;
372                    
373                    // lets iterate the /*
374                    for input in &sh.mapping.live_instances.inputs {
375                        if input.id == id {
376                            for j in 0..repeat {
377                                for i in 0..input.slots {
378                                    instances[input.offset + i + j * stride] = inst_slice[input.offset + i]
379                                }
380                            }
381                            draw_call.instance_dirty = true;
382                        }
383                    }
384                    for input in &sh.mapping.user_uniforms.inputs {
385                        if input.id == id {
386                            for i in 0..input.slots {
387                                draw_call.user_uniforms[input.offset + i] = self.user_uniforms[input.offset + i]
388                            }
389                        }
390                        draw_call.uniforms_dirty = true;
391                    }
392                    node_iter = nodes.next_child(node_index);
393                }
394                // DONE!
395                cx.passes[draw_list.pass_id.unwrap()].paint_dirty = true;
396            }
397        }
398    }
399    
400    pub fn update_rect(&mut self, cx: &mut Cx, rect: Rect) {
401        if let Some(draw_shader) = self.draw_shader {
402            if let Some(inst) = self.area.valid_instance(cx) {
403                if draw_shader.draw_shader_generation != cx.draw_shaders.generation {
404                    return;
405                }
406                let sh = &cx.draw_shaders[draw_shader.draw_shader_id];
407                let draw_list = &mut cx.draw_lists[inst.draw_list_id];
408                let draw_item = &mut draw_list.draw_items[inst.draw_item_id];
409                let draw_call = draw_item.kind.draw_call_mut().unwrap();
410                
411                let repeat = inst.instance_count;
412                let stride = sh.mapping.instances.total_slots;
413                let instances = &mut draw_item.instances.as_mut().unwrap()[inst.instance_offset..];
414                
415                for input in &sh.mapping.instances.inputs {
416                    if input.id == live_id!(rect_pos) {
417                        for j in 0..repeat {
418                            instances[input.offset + 0 + j * stride] = rect.pos.x as f32;
419                            instances[input.offset + 1 + j * stride] = rect.pos.y as f32;
420                        }
421                    }
422                    if input.id == live_id!(rect_size) {
423                        for j in 0..repeat {
424                            instances[input.offset + 0 + j * stride] = rect.size.x as f32;
425                            instances[input.offset + 1 + j * stride] = rect.size.y as f32;
426                        }
427                    }
428                }
429                draw_call.instance_dirty = true;
430                cx.passes[draw_list.pass_id.unwrap()].paint_dirty = true;
431            }
432        }
433    }
434    
435    pub fn update_area_with_value(&mut self, cx: &mut Cx, id: LiveId, v: &[f32], start: usize, count: usize) {
436        if let Some(draw_shader) = self.draw_shader {
437            if let Some(inst) = self.area.valid_instance(cx) {
438                if draw_shader.draw_shader_generation != cx.draw_shaders.generation {
439                    return;
440                }
441                let sh = &cx.draw_shaders[draw_shader.draw_shader_id];
442                let draw_list = &mut cx.draw_lists[inst.draw_list_id];
443                let draw_item = &mut draw_list.draw_items[inst.draw_item_id];
444                let draw_call = draw_item.kind.draw_call_mut().unwrap();
445                
446                let repeat = inst.instance_count.min(count);
447                let stride = sh.mapping.instances.total_slots;
448                let instances = &mut draw_item.instances.as_mut().unwrap()[inst.instance_offset..];
449                
450                cx.passes[draw_list.pass_id.unwrap()].paint_dirty = true;
451                
452                // lets iterate the /*
453                for input in &sh.mapping.live_instances.inputs {
454                    if input.id == id {
455                        for j in start..(start + repeat) {
456                            for i in 0..input.slots {
457                                instances[input.offset + i + j * stride] = v[i]
458                            }
459                        }
460                        draw_call.instance_dirty = true;
461                    }
462                    return
463                }
464                for input in &sh.mapping.user_uniforms.inputs {
465                    if input.id == id {
466                        for i in 0..input.slots {
467                            draw_call.user_uniforms[input.offset + i] = v[i]
468                        }
469                        draw_call.uniforms_dirty = true;
470                        return
471                    }
472                }
473            }
474        }
475    }
476    
477    pub fn get_instance(&self, cx: &mut Cx, inst: &[LiveId], value: &mut [f32]){
478        if let Some(draw_shader) = self.draw_shader {
479            let sh = &cx.draw_shaders[draw_shader.draw_shader_id];
480            let self_slice = self.as_slice();
481            for input in &sh.mapping.instances.inputs {
482                let offset = input.offset;
483                let slots = input.slots;
484                if input.id == inst[0] {
485                    for i in 0..value.len().min(slots) {
486                        value[i] = self_slice[offset + i]
487                    }
488                }
489            }
490        }
491    }
492    
493    pub fn set_var_instance(&mut self, cx:&Cx, instance: &[LiveId], value: &[f32]) {
494        if let Some(draw_shader) = self.draw_shader {
495            let sh = &cx.draw_shaders[draw_shader.draw_shader_id];
496            for input in &sh.mapping.var_instances.inputs {
497                let offset = (self.var_instances.len() - sh.mapping.var_instances.total_slots) + input.offset;
498                let slots = input.slots;
499                if input.id == instance[0] {
500                    for i in 0..value.len().min(slots) {
501                        self.var_instances[offset + i] = value[i];
502                    }
503                }
504            }
505        }
506    }
507    
508    pub fn get_uniform(&self, cx: &mut Cx, uniform: &[LiveId], value: &mut [f32]){
509        if let Some(draw_shader) = self.draw_shader {
510            let sh = &cx.draw_shaders[draw_shader.draw_shader_id];
511            for input in &sh.mapping.user_uniforms.inputs {
512                let offset = input.offset;
513                let slots = input.slots;
514                if input.id == uniform[0] {
515                    for i in 0..value.len().min(slots) {
516                        value[i] = self.user_uniforms[offset + i];
517                    }
518                }
519            }
520        }
521    }
522    
523    pub fn set_uniform(&mut self, cx:&Cx, uniform: &[LiveId], value: &[f32]) {
524        if let Some(draw_shader) = self.draw_shader {
525            let sh = &cx.draw_shaders[draw_shader.draw_shader_id];
526            for input in &sh.mapping.user_uniforms.inputs {
527                let offset = input.offset;
528                let slots = input.slots;
529                if input.id == uniform[0] {
530                    for i in 0..value.len().min(slots) {
531                        self.user_uniforms[offset + i] = value[i]
532                    }
533                }
534            }
535        }
536    }
537    
538        
539    pub fn init_slicer(
540        &mut self,
541        cx: &mut Cx,
542    ) {
543        if let Some(draw_shader) = self.draw_shader {
544            let sh = &cx.draw_shaders[draw_shader.draw_shader_id];
545            self.var_instance_start = self.var_instances.len() - sh.mapping.var_instances.total_slots;
546            self.var_instance_slots = sh.mapping.instances.total_slots;
547        }
548    }
549    
550    pub fn before_apply_init_shader(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, _nodes: &[LiveNode], geometry_fields: &dyn GeometryFields) {
551        
552        let draw_shader_ptr = if let Some(file_id) = from.file_id() {
553            let generation = cx.live_registry.borrow().file_id_to_file(file_id).generation;
554            DrawShaderPtr(LivePtr::from_index(file_id, index, generation))
555        }
556        else {
557            return
558        };
559        self.init_shader(cx, from, draw_shader_ptr, geometry_fields)
560    }
561    
562    pub fn apply_slots(cx: &mut Cx, slots: usize, output: &mut [f32], offset: usize, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
563        match slots {
564            1 => {
565                let mut v: f32 = 0.0;
566                let index = v.apply(cx, from, index, nodes);
567                output[offset + 0] = v;
568                return index;
569            }
570            2 => {
571                let mut v: Vec2 = Vec2::default();
572                let index = v.apply(cx, from, index, nodes);
573                output[offset + 0] = v.x;
574                output[offset + 1] = v.y;
575                return index;
576            }
577            3 => {
578                let mut v: Vec3 = Vec3::default();
579                let index = v.apply(cx, from, index, nodes);
580                output[offset + 0] = v.x;
581                output[offset + 1] = v.y;
582                output[offset + 2] = v.z;
583                return index;
584            }
585            4 => {
586                let mut v: Vec4 = Vec4::default();
587                let index = v.apply(cx, from, index, nodes);
588                output[offset + 0] = v.x;
589                output[offset + 1] = v.y;
590                output[offset + 2] = v.z;
591                output[offset + 3] = v.w;
592                return index;
593            }
594            _ => {
595                return nodes.skip_node(index)
596            }
597        }
598    }
599    
600    pub fn apply_value(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode]) -> usize {
601        
602        if nodes[index].origin.node_has_prefix() && nodes[index].value.is_id() {
603            return nodes.skip_node(index)
604        }
605        
606        if let Some(draw_shader) = self.draw_shader {
607            let id = nodes[index].id;
608            if draw_shader.draw_shader_generation != cx.draw_shaders.generation {
609                return nodes.skip_node(index);
610            }
611            let sh = &cx.draw_shaders[draw_shader.draw_shader_id];
612            for input in &sh.mapping.user_uniforms.inputs {
613                let offset = input.offset;
614                let slots = input.slots;
615                if input.id == id {
616                    return Self::apply_slots(cx, slots, &mut self.user_uniforms, offset, from, index, nodes);
617                }
618            }
619            for input in &sh.mapping.var_instances.inputs {
620                
621                let offset = (self.var_instances.len() - sh.mapping.var_instances.total_slots) + input.offset;
622                let slots = input.slots;
623                if input.id == id {
624                    return Self::apply_slots(cx, slots, &mut self.var_instances, offset, from, index, nodes);
625                }
626            }
627        }
628        else { // our shader simply didnt compile
629            return nodes.skip_node(index);
630        }
631        
632        if nodes[index].origin.node_has_prefix() {
633            return nodes.skip_node(index)
634        }
635        
636        let unknown_shader_props = match nodes[index].id {
637            live_id!(debug) => false,
638            live_id!(debug_id) => false,
639            live_id!(draw_call_group) => false,
640            _ => true
641        };
642        
643        if unknown_shader_props && nodes[index].value.is_value_type() {
644            cx.apply_error_no_matching_field(live_error_origin!(), index, nodes);
645        }
646        nodes.skip_node(index)
647    }
648    
649    pub fn after_apply_update_self(&mut self, cx: &mut Cx, from: ApplyFrom, index: usize, nodes: &[LiveNode], geometry_fields: &dyn GeometryFields) {
650        // alright. so.if we are ApplyFrom::
651        if from.is_from_doc() {
652            self.init_slicer(cx);
653        }
654        self.geometry_id = geometry_fields.get_geometry_id();
655        self.update_area_with_self(cx, index, nodes);
656    }
657    
658}
659