Загрузка данных


(defun c:DONUTHAND ( / old_cmd old_osm old_dyn old_blip
pi_val two_pi
v-add v-sub v-scale v-len v-norm v-cross v-dot v-lerp
catmull-rom-pt calc-frame
make-truecolor-mesh make-swept-organ
make-nail-mesh make-capsule-sprinkle
build-donut-base build-icing-mesh build-all-sprinkles
build-seamless-hand build-all-fingers)
;; Сохранение и отключение системных привязок и эха для мгновенной генерации
(setq old_cmd (getvar "CMDECHO"))
(setq old_osm (getvar "OSMODE"))
(setq old_dyn (getvar "DYNMODE"))
(setq old_blip (getvar "BLIPMODE"))
(setvar "CMDECHO" 0)
(setvar "OSMODE" 0)
(if old_dyn (setvar "DYNMODE" 0))
(if old_blip (setvar "BLIPMODE" 0))
;; Очистка предыдущей модели на чертеже, чтобы старая рука не накладывалась
(command "_.ERASE" "_ALL" "")
(setq pi_val 3.14159265358979323846)
(setq two_pi (* 2.0 pi_val))
(princ "\n[1/5] Инициализация математического ядра 3D-скульптинга...")
;; ==========================================================================
;; 1. БИБЛИОТЕКА ВЕКТОРНОЙ АЛГЕБРЫ И СПЛАЙНОВОЙ ИНТЕРПОЛЯЦИИ
;; ==========================================================================
(defun v-add (a b) (mapcar '+ a b))
(defun v-sub (a b) (mapcar '- a b))
(defun v-scale (a s) (mapcar '(lambda (x) (* x s)) a))
(defun v-dot (a b) (apply '+ (mapcar '* a b)))
(defun v-len (a)
(sqrt (apply '+ (mapcar '(lambda (x) (* x x)) a)))
)
(defun v-norm (a / l)
(setq l (v-len a))
(if (> l 1e-8)
(v-scale a (/ 1.0 l))
'(0.0 0.0 1.0)
)
)
(defun v-cross (a b)
(list
(- (* (nth 1 a) (nth 2 b)) (* (nth 2 a) (nth 1 b)))
(- (* (nth 2 a) (nth 0 b)) (* (nth 0 a) (nth 2 b)))
(- (* (nth 0 a) (nth 1 b)) (* (nth 1 a) (nth 0 b)))
)
)
(defun v-lerp (a b t_param)
(v-add a (v-scale (v-sub b a) t_param))
)
;; Гладкая интерполяция сплайном Катмулла-Рома по 4 точкам (t от 0.0 до 1.0)
(defun catmull-rom-pt (p0 p1 p2 p3 t_val / t2 t3 c0 c1 c2 c3)
(setq t2 (* t_val t_val)
t3 (* t2 t_val)
c0 (+ (* -0.5 t3) (* 1.0 t2) (* -0.5 t_val))
c1 (+ (*  1.5 t3) (* -2.5 t2) 1.0)
c2 (+ (* -1.5 t3) (* 2.0 t2) (* 0.5 t_val))
c3 (+ (*  0.5 t3) (* -0.5 t2)))
(v-add
(v-add (v-scale p0 c0) (v-scale p1 c1))
(v-add (v-scale p2 c2) (v-scale p3 c3))
)
)
;; Вычисление локальной ортонормированной системы координат (T, N, B) вдоль кривой
(defun calc-frame (tan_vec up_hint / t_n n_vec b_vec)
(setq t_n (v-norm tan_vec))
(if (< (abs (v-dot t_n up_hint)) 0.95)
(setq b_vec (v-norm (v-cross t_n up_hint)))
(setq b_vec (v-norm (v-cross t_n '(0.0 0.0 1.0))))
)
(setq n_vec (v-norm (v-cross b_vec t_n)))
(list t_n n_vec b_vec)
)
;; ==========================================================================
;; 2. ЯДРО ГЕНЕРАЦИИ 3D-СЕТОК С ПОДДЕРЖКОЙ TRUECOLOR (24-BIT RGB)
;; ==========================================================================
(defun make-truecolor-mesh (pts_grid m_cnt n_cnt close_m close_n aci_col rgb_list
/ flag_bits true_col header_data row_pts pt_xyz vtx_data)
(setq flag_bits 16)
(if close_m (setq flag_bits (+ flag_bits 1)))
(if close_n (setq flag_bits (+ flag_bits 32)))
(setq true_col (+ (lsh 1 24)
(lsh (nth 0 rgb_list) 16)
(lsh (nth 1 rgb_list) 8)
(nth 2 rgb_list)))
(setq header_data
(list
'(0 . "POLYLINE")
'(100 . "AcDbEntity")
(cons 62 aci_col)
(cons 420 true_col)
'(100 . "AcDbPolygonMesh")
'(66 . 1)
'(10 0.0 0.0 0.0)
(cons 70 flag_bits)
(cons 71 m_cnt)
(cons 72 n_cnt)
)
)
(entmake header_data)
(foreach row_pts pts_grid
(foreach pt_xyz row_pts
(setq vtx_data
(list
'(0 . "VERTEX")
'(100 . "AcDbEntity")
(cons 62 aci_col)
(cons 420 true_col)
'(100 . "AcDbVertex")
'(100 . "AcDbPolygonMeshVertex")
(cons 10 pt_xyz)
'(70 . 64)
)
)
(entmake vtx_data)
)
)
(entmake (list '(0 . "SEQEND") (cons 62 aci_col) (cons 420 true_col)))
)
;; Генератор органической скульптурной формы вдоль сплайна с ориентацией сечений
(defun make-swept-organ (ctrl_pts sub_steps n_seg cap_start cap_end up_vec aci_col rgb_list
/ ext_pts num_ctrl spine_list i p0 p1 p2 p3 step_idx t_val
pt_c rx_c ry_c b_c total_rings idx tan_v
frame_v n_v b_v grid_rows ring_item j ang cos_a sin_a
flat_bottom local_x local_y world_pt
first_sp last_sp cap_ring k cap_ang)
(setq ext_pts (append (list (car ctrl_pts)) ctrl_pts (list (last ctrl_pts))))
(setq num_ctrl (length ctrl_pts))
(setq spine_list nil)
(setq i 0)
(while (< i (1- num_ctrl))
(setq p0 (nth i ext_pts)
p1 (nth (1+ i) ext_pts)
p2 (nth (+ i 2) ext_pts)
p3 (nth (+ i 3) ext_pts))
(setq step_idx 0)
(while (< step_idx sub_steps)
(setq t_val (/ (float step_idx) (float sub_steps)))
(setq pt_c (catmull-rom-pt
(list (nth 0 p0) (nth 1 p0) (nth 2 p0))
(list (nth 0 p1) (nth 1 p1) (nth 2 p1))
(list (nth 0 p2) (nth 1 p2) (nth 2 p2))
(list (nth 0 p3) (nth 1 p3) (nth 2 p3))
t_val))
(setq rx_c (+ (nth 3 p1) (* (- (nth 3 p2) (nth 3 p1)) t_val)))
(setq ry_c (+ (nth 4 p1) (* (- (nth 4 p2) (nth 4 p1)) t_val)))
(setq b_c  (+ (nth 5 p1) (* (- (nth 5 p2) (nth 5 p1)) t_val)))
(setq spine_list (append spine_list (list (list pt_c rx_c ry_c b_c))))
(setq step_idx (1+ step_idx))
)
(setq i (1+ i))
)
(setq p2 (last ctrl_pts))
(setq spine_list
(append spine_list
(list (list (list (nth 0 p2) (nth 1 p2) (nth 2 p2))
(nth 3 p2) (nth 4 p2) (nth 5 p2)))))
(setq total_rings (length spine_list))
(setq grid_rows nil)
(if cap_start
(progn
(setq first_sp (car spine_list))
(setq pt_c (nth 0 first_sp)
rx_c (nth 1 first_sp)
ry_c (nth 2 first_sp))
(setq tan_v (v-norm (v-sub (nth 0 (nth 1 spine_list)) pt_c)))
(setq frame_v (calc-frame tan_v up_vec)
n_v (nth 1 frame_v)
b_v (nth 2 frame_v))
(setq k 3)
(while (> k 0)
(setq cap_ang (* (/ (float k) 3.5) (* 0.5 pi_val)))
(setq cap_ring nil
j 0)
(while (< j n_seg)
(setq ang (* (/ (float j) (float n_seg)) two_pi)
cos_a (cos ang)
sin_a (sin ang))
(setq world_pt
(v-add
(v-sub pt_c (v-scale tan_v (* 0.65 rx_c (sin cap_ang))))
(v-add
(v-scale n_v (* rx_c (cos cap_ang) cos_a))
(v-scale b_v (* ry_c (cos cap_ang) sin_a))
)
)
)
(setq cap_ring (append cap_ring (list world_pt)))
(setq j (1+ j))
)
(setq grid_rows (append grid_rows (list cap_ring)))
(setq k (1- k))
)
)
)
(setq idx 0)
(while (< idx total_rings)
(setq ring_item (nth idx spine_list)
pt_c (nth 0 ring_item)
rx_c (nth 1 ring_item)
ry_c (nth 2 ring_item)
b_c  (nth 3 ring_item))
(cond
((= idx 0)
(setq tan_v (v-sub (nth 0 (nth 1 spine_list)) pt_c)))
((= idx (1- total_rings))
(setq tan_v (v-sub pt_c (nth 0 (nth (- idx 1) spine_list)))))
(T
(setq tan_v (v-sub (nth 0 (nth (1+ idx) spine_list))
(nth 0 (nth (1- idx) spine_list)))))
)
(setq frame_v (calc-frame tan_v up_vec)
n_v (nth 1 frame_v)
b_v (nth 2 frame_v))
(setq cap_ring nil
j 0)
(while (< j n_seg)
(setq ang (* (/ (float j) (float n_seg)) two_pi)
cos_a (cos ang)
sin_a (sin ang))
;; Анатомический профиль пальца: мягкая подушечка изнутри и гладкая спинка снаружи
(setq flat_bottom (+ 1.0 (* b_c (cos ang)) (* -0.04 (cos (* 2.0 ang)))))
(setq local_x (* rx_c cos_a flat_bottom)
local_y (* ry_c sin_a))
(setq world_pt
(v-add pt_c
(v-add (v-scale n_v local_x)
(v-scale b_v local_y))))
(setq cap_ring (append cap_ring (list world_pt)))
(setq j (1+ j))
)
(setq grid_rows (append grid_rows (list cap_ring)))
(setq idx (1+ idx))
)
;; Мягкий анатомический кончик пальца
(if cap_end
(progn
(setq last_sp (last spine_list))
(setq pt_c (nth 0 last_sp)
rx_c (nth 1 last_sp)
ry_c (nth 2 last_sp))
(setq tan_v (v-norm (v-sub pt_c (nth 0 (nth (- total_rings 2) spine_list)))))
(setq frame_v (calc-frame tan_v up_vec)
n_v (nth 1 frame_v)
b_v (nth 2 frame_v))
(setq k 1)
(while (<= k 4)
(setq cap_ang (* (/ (float k) 4.15) (* 0.5 pi_val)))
(setq cap_ring nil
j 0)
(while (< j n_seg)
(setq ang (* (/ (float j) (float n_seg)) two_pi)
cos_a (cos ang)
sin_a (sin ang))
(setq world_pt
(v-add
(v-add pt_c (v-scale tan_v (* 0.92 rx_c (sin cap_ang))))
(v-add
(v-scale n_v (* rx_c (cos cap_ang) cos_a))
(v-scale b_v (* ry_c (cos cap_ang) sin_a))
)
)
)
(setq cap_ring (append cap_ring (list world_pt)))
(setq j (1+ j))
)
(setq grid_rows (append grid_rows (list cap_ring)))
(setq k (1+ k))
)
)
)
(make-truecolor-mesh grid_rows (length grid_rows) n_seg nil T aci_col rgb_list)
)
;; Генератор реалистичного 3D-ноготка с поперечной аркой, лежащего четко на спинке пальца
(defun make-nail-mesh (base_pt tip_pt outward_nrm width_val curve_h
/ dir_v len_val nrm_v side_v m_rows n_cols i j u_t v_t
width_scale arch_z len_curve pt_nail grid_rows row_pts)
(setq len_val (v-len (v-sub tip_pt base_pt)))
(setq dir_v (v-norm (v-sub tip_pt base_pt)))
(setq nrm_v (v-norm outward_nrm))
(setq side_v (v-norm (v-cross dir_v nrm_v)))
(setq nrm_v (v-norm (v-cross side_v dir_v)))
(setq m_rows 9
n_cols 11
grid_rows nil
i 0)
(while (< i m_rows)
(setq u_t (/ (float i) (float (1- m_rows))))
;; Овальное скругление у кутикулы и на кончике ногтя
(setq width_scale (- 1.0 (* 0.34 (expt (- (* 2.0 u_t) 0.95) 2))))
(setq len_curve (* 0.22 curve_h (sin (* u_t pi_val))))
(setq row_pts nil
j 0)
(while (< j n_cols)
(setq v_t (- (/ (float j) (float (1- n_cols))) 0.5))
(setq arch_z (* curve_h (cos (* v_t pi_val 0.95))))
(setq pt_nail
(v-add base_pt
(v-add
(v-scale dir_v (* u_t len_val))
(v-add
(v-scale side_v (* v_t width_val width_scale))
(v-scale nrm_v (+ arch_z len_curve))
)
)
)
)
(setq row_pts (append row_pts (list pt_nail)))
(setq j (1+ j))
)
(setq grid_rows (append grid_rows (list row_pts)))
(setq i (1+ i))
)
;; Нежно-жемчужный розовый цвет ногтя
(make-truecolor-mesh grid_rows m_rows n_cols nil nil 9 '(255 226 224))
)
;; ==========================================================================
;; 3. ПОСТРОЕНИЕ ПОНЧИКА, СВЕТЛОЙ ПОЛОСКИ И ВОЛНИСТОЙ ГЛАЗУРИ С КАПЛЯМИ
;; ==========================================================================
(defun build-donut-base ( / m_tor n_tor i j u_ang v_ang cos_u sin_u cos_v sin_v
R_maj r_min r_eff x_p y_p z_p
grid_dough row_pts
grid_belt belt_rows v_belt)
(princ "\n[2/5] Моделирование пышного теста пончика и светлого пояска...")
(setq R_maj 54.0
r_min 26.5
m_tor 64
n_tor 36
grid_dough nil
i 0)
(while (< i m_tor)
(setq u_ang (* (/ (float i) (float m_tor)) two_pi)
cos_u (cos u_ang)
sin_u (sin u_ang)
row_pts nil
j 0)
(while (< j n_tor)
(setq v_ang (* (/ (float j) (float n_tor)) two_pi)
cos_v (cos v_ang)
sin_v (sin v_ang))
(setq r_eff (+ R_maj
(* r_min cos_v)
(* 0.40 (sin (* 5.0 u_ang)) (cos v_ang))))
(setq z_p (* r_min 0.84 sin_v))
(setq x_p (* r_eff cos_u)
y_p (* r_eff sin_u))
(setq row_pts (append row_pts (list (list x_p y_p z_p))))
(setq j (1+ j))
)
(setq grid_dough (append grid_dough (list row_pts)))
(setq i (1+ i))
)
(make-truecolor-mesh grid_dough m_tor n_tor T T 30 '(232 138 48))
;; Светлая полоска посередине боковины пончика
(setq grid_belt nil
belt_rows 7
i 0)
(while (< i m_tor)
(setq u_ang (* (/ (float i) (float m_tor)) two_pi)
cos_u (cos u_ang)
sin_u (sin u_ang)
row_pts nil
j 0)
(while (< j belt_rows)
(setq v_belt (* (- (/ (float j) (float (1- belt_rows))) 0.5) 0.26))
(setq r_eff (+ R_maj (* (+ r_min 0.22) (cos v_belt))))
(setq z_p (* r_min 0.84 (sin v_belt)))
(setq row_pts (append row_pts (list (list (* r_eff cos_u) (* r_eff sin_u) z_p))))
(setq j (1+ j))
)
(setq grid_belt (append grid_belt (list row_pts)))
(setq i (1+ i))
)
(make-truecolor-mesh grid_belt m_tor belt_rows T nil 51 '(249 194 128))
)
(defun build-icing-mesh ( / m_ice n_ice i j u_ang t_v
R_maj r_min drip_wave crease_wave
v_start v_end v_ang cos_u sin_u cos_v sin_v
thick_offset lip_bulge inner_fold
r_curr r_eff x_p y_p z_p
grid_ice row_pts)
(princ "\n[3/5] Генерация глянцевой розовой глазури со складками и подтеками...")
(setq R_maj 54.0
r_min 26.5
m_ice 96
n_ice 32
grid_ice nil
i 0)
(while (< i m_ice)
(setq u_ang (* (/ (float i) (float m_ice)) two_pi)
cos_u (cos u_ang)
sin_u (sin u_ang))
;; Красивые мягкие волны и капли глазури (особенно в промежутках между пальцами)
(setq drip_wave
(+ (* 0.13 (sin (* 5.0 u_ang)))
(* 0.17 (cos (- (* 8.0 u_ang) 0.5)))
(* 0.10 (sin (+ (* 13.0 u_ang) 1.2)))
;; Выразительная капля глазури ровно между указательным и большим пальцем (как на фото!)
(* 0.22 (exp (* -18.0 (expt (sin (* 0.5 (- u_ang 4.30))) 2))))
;; Капля справа от большого пальца
(* 0.18 (exp (* -16.0 (expt (sin (* 0.5 (- u_ang 4.92))) 2))))
)
)
(setq crease_wave
(+ (* 0.55 (sin (* 18.0 u_ang)))
(* 0.35 (cos (* 27.0 u_ang)))
)
)
(setq v_start (- -0.13 drip_wave)
v_end   (+ pi_val 0.22)
row_pts nil
j 0)
(while (< j n_ice)
(setq t_v (/ (float j) (float (1- n_ice))))
(setq v_ang (+ v_start (* t_v (- v_end v_start)))
cos_v (cos v_ang)
sin_v (sin v_ang))
(setq lip_bulge (* 1.30 (exp (* -28.0 (expt t_v 2)))))
(setq inner_fold (* crease_wave (expt (sin (* t_v 0.85 pi_val)) 2) (if (> t_v 0.45) 1.0 0.25)))
(setq thick_offset (+ 1.60 lip_bulge (* 0.45 (sin (* t_v pi_val))) (* 0.35 inner_fold)))
(setq r_curr (+ r_min thick_offset))
(setq r_eff (+ R_maj (* r_curr cos_v)))
(setq z_p (+ (* r_curr 0.85 sin_v) 0.55 (* 0.25 inner_fold)))
(setq x_p (* r_eff cos_u)
y_p (* r_eff sin_u))
(setq row_pts (append row_pts (list (list x_p y_p z_p))))
(setq j (1+ j))
)
(setq grid_ice (append grid_ice (list row_pts)))
(setq i (1+ i))
)
(make-truecolor-mesh grid_ice m_ice n_ice T nil 241 '(252 126 178))
)
;; ==========================================================================
;; 4. ГЕНЕРАЦИЯ 88 КАПСУЛ РАЗНОЦВЕТНОЙ КОНДИТЕРСКОЙ ПОСЫПКИ
;; ==========================================================================
(defun make-capsule-sprinkle (u_deg v_deg rot_deg col_id
/ u_rad v_rad rot_rad R_maj r_ice
cos_u sin_u cos_v sin_v
pt_surf nrm_surf tan_u tan_v dir_spr
spr_rad spr_hlen p_start p_end
aci_c rgb_c ctrl_spr)
(setq u_rad (* u_deg (/ pi_val 180.0))
v_rad (* v_deg (/ pi_val 180.0))
rot_rad (* rot_deg (/ pi_val 180.0))
R_maj 54.0
r_ice 28.4)
(setq cos_u (cos u_rad) sin_u (sin u_rad)
cos_v (cos v_rad) sin_v (sin v_rad))
(setq pt_surf
(list
(* (+ R_maj (* r_ice cos_v)) cos_u)
(* (+ R_maj (* r_ice cos_v)) sin_u)
(+ (* r_ice 0.85 sin_v) 0.65)
)
)
(setq nrm_surf (v-norm (list (* cos_v cos_u) (* cos_v sin_u) (/ sin_v 0.85))))
(setq tan_u (list (- sin_u) cos_u 0.0))
(setq tan_v (v-norm (v-cross nrm_surf tan_u)))
(setq dir_spr (v-norm (v-add (v-scale tan_u (cos rot_rad))
(v-scale tan_v (sin rot_rad)))))
(setq spr_rad 1.25
spr_hlen 2.35)
(setq pt_surf (v-add pt_surf (v-scale nrm_surf 0.55)))
(setq p_start (v-sub pt_surf (v-scale dir_spr spr_hlen))
p_end   (v-add pt_surf (v-scale dir_spr spr_hlen)))
(cond
((= col_id 1) (setq aci_c 7   rgb_c '(252 252 255))) ;; Белый
((= col_id 2) (setq aci_c 140 rgb_c '(58 192 248)))  ;; Голубой
((= col_id 3) (setq aci_c 92  rgb_c '(82 218 142)))  ;; Мятно-зеленый
((= col_id 4) (setq aci_c 40  rgb_c '(255 182 54)))  ;; Желто-оранжевый
((= col_id 5) (setq aci_c 191 rgb_c '(196 138 242))) ;; Лавандовый
(T            (setq aci_c 230 rgb_c '(255 96 158)))  ;; Ярко-розовый
)
(setq ctrl_spr
(list
(list (nth 0 p_start) (nth 1 p_start) (nth 2 p_start) spr_rad spr_rad 0.0)
(list (nth 0 pt_surf) (nth 1 pt_surf) (nth 2 pt_surf) spr_rad spr_rad 0.0)
(list (nth 0 p_end)   (nth 1 p_end)   (nth 2 p_end)   spr_rad spr_rad 0.0)
)
)
(make-swept-organ ctrl_spr 1 8 T T nrm_surf aci_c rgb_c)
)
(defun build-all-sprinkles ( / s_list item)
(princ "\n[4/5] Раскладка 88 объемных капсул кондитерской посыпки...")
(setq s_list
'(
(246 18 35 3)  (252 32 -20 1) (258 55 48 4)  (264 20 -65 3) (270 42 15 1)
(276 14 80 2)  (282 28 -35 6) (288 52 12 2)  (294 16 45 4)  (300 38 -50 1)
(306 10 25 2)  (312 30 -15 5) (318 58 60 1)  (324 22 -40 4) (330 44 30 3)
(336 12 -70 1) (342 36 18 2)  (348 62 -25 5) (354 20 55 4)  (238 26 -12 4)
(232 48 65 1)  (225 22 -45 6) (218 38 22 4)  (212 58 -30 3) (205 28 40 1)
(0   45 -20 3) (8   25 50 1)  (16  68 -35 5) (24  38 15 4)  (32  82 -60 2)
(40  52 30 1)  (48  22 -15 6) (56  72 45 3)  (64  42 -50 4) (72  88 20 1)
(80  58 -25 2) (88  30 65 5)  (96  75 -40 4) (104 48 12 3)  (112 85 -18 1)
(120 55 35 2)  (128 28 -55 4) (136 72 25 5)  (144 45 -30 3) (152 82 50 1)
(160 52 -15 4) (168 25 40 2)  (176 68 -45 5) (184 42 18 1)  (192 78 -22 3)
(200 48 60 2)  (210 82 -35 4) (222 72 15 1)  (235 85 -50 3) (248 78 28 2)
(260 88 -15 5) (274 76 42 4)  (286 86 -30 1) (298 74 55 3)  (310 84 -20 6)
(322 76 35 2)  (335 88 -45 4) (346 75 15 1)
(15  118 25 4) (35  128 -40 2) (55  115 60 1) (75  132 -15 3) (95  120 35 5)
(115 135 -50 4)(135 118 20 2)  (155 130 -30 1)(175 115 45 3)  (195 128 -25 6)
(215 118 55 2) (235 132 -40 5) (255 122 15 3) (275 135 -60 4) (295 118 30 2)
(315 130 -20 5)(335 116 48 1)  (355 128 -35 4)
(266 8   10 3) (290 8   -25 1) (316 12  40 2) (244 10  -15 4) (230 18  30 1)
(278 64  -55 5)(250 62  20 2)
)
)
(foreach item s_list
(make-capsule-sprinkle (nth 0 item) (nth 1 item) (nth 2 item) (nth 3 item))
)
)
;; ==========================================================================
;; 5. ЕДИНАЯ БЕСШОВНАЯ СКУЛЬПТУРНАЯ ЛАДОНЬ И ПАЛЬЦЫ (БЕЗ ПЕРЕСЕЧЕНИЯ ПОНЧИКА)
;; ==========================================================================
(defun build-seamless-hand ( / skin_rgb skin_aci
palm_sections ext_sec num_sec sub_s
interp_sec i s0 s1 s2 s3 step_i t_v
cx cy cz ux uy uz vx vy vz th_b cup_d
grid_rows n_seg item j ang cos_a sin_a
r_mod thenar_bump cup_z px py pz row_pts)
(princ "\n[5/5] Построение бесшовной скульптурной ладони и точной анатомии пальцев...")
(setq skin_rgb '(246 184 156)
skin_aci 41)
;; Единая система плавных анатомических сечений от предплечья через запястье
;; и возвышение большого пальца (тенар) до широкой чаши ладони под пончиком.
;; Никаких отдельных шаров и труб!
;; Формат каждого сечения: (CX CY CZ  UX UY UZ  VX VY VZ  THENAR_BULGE  CUP_DEPTH)
(setq palm_sections
'(
;; 1. Изящное предплечье, уходящее в правый нижний угол кадра (как на фото)
( 78.0   2.0 -106.0   13.0 -15.0  4.0    7.0  6.0 11.0   0.00  0.0)
;; 2. Нижняя треть предплечья
( 60.0  -3.0  -84.0   14.0 -15.5  4.5    6.8  6.0 10.5   0.05  0.5)
;; 3. Изящное анатомическое запястье (легкий прогиб)
( 44.0  -8.0  -64.0   16.5 -16.5  5.5    6.2  5.8  9.5   0.18  1.5)
;; 4. Пятка ладони и начало мягкого возвышения большого пальца (тенара)
( 27.0 -16.0  -47.0   24.0 -18.0  7.5    7.5  6.5 11.0   0.48  4.0)
;; 5. Широкая середина ладони и мышца большого пальца справа спереди
(  6.0 -23.0  -37.0   32.0 -16.0  8.0    7.0  6.5 10.5   0.52  6.5)
;; 6. Пястная дуга (чаша ладони прямо под пончиком, откуда растут 4 пальца)
(-19.0 -23.0  -31.0   33.0  -8.0  5.5    5.5  5.5  8.5   0.18  5.0)
;; 7. Плавное скругление края ладони у основания пальцев
(-36.0 -17.0  -26.0   24.0   2.0  4.0    4.0  4.0  6.0   0.00  2.0)
(-43.0 -12.0  -23.0    8.0   2.0  1.5    1.5  1.5  2.0   0.00  0.0)
)
)
;; Сплайновая интерполяция сечений ладони (Catmull-Rom) для идеальной гладкости
(setq ext_sec (append (list (car palm_sections)) palm_sections (list (last palm_sections))))
(setq num_sec (length palm_sections))
(setq sub_s 5)
(setq interp_sec nil)
(setq i 0)
(while (< i (1- num_sec))
(setq s0 (nth i ext_sec)
s1 (nth (1+ i) ext_sec)
s2 (nth (+ i 2) ext_sec)
s3 (nth (+ i 3) ext_sec))
(setq step_i 0)
(while (< step_i sub_s)
(setq t_v (/ (float step_i) (float sub_s)))
(setq pt_c (catmull-rom-pt
(list (nth 0 s0) (nth 1 s0) (nth 2 s0))
(list (nth 0 s1) (nth 1 s1) (nth 2 s1))
(list (nth 0 s2) (nth 1 s2) (nth 2 s2))
(list (nth 0 s3) (nth 1 s3) (nth 2 s3))
t_v))
(setq u_c (catmull-rom-pt
(list (nth 3 s0) (nth 4 s0) (nth 5 s0))
(list (nth 3 s1) (nth 4 s1) (nth 5 s1))
(list (nth 3 s2) (nth 4 s2) (nth 5 s2))
(list (nth 3 s3) (nth 4 s3) (nth 5 s3))
t_v))
(setq v_c (catmull-rom-pt
(list (nth 6 s0) (nth 7 s0) (nth 8 s0))
(list (nth 6 s1) (nth 7 s1) (nth 8 s1))
(list (nth 6 s2) (nth 7 s2) (nth 8 s2))
(list (nth 6 s3) (nth 7 s3) (nth 8 s3))
t_v))
(setq th_b  (+ (nth 9 s1)  (* (- (nth 9 s2)  (nth 9 s1))  t_v)))
(setq cup_d (+ (nth 10 s1) (* (- (nth 10 s2) (nth 10 s1)) t_v)))
(setq interp_sec (append interp_sec (list (list pt_c u_c v_c th_b cup_d))))
(setq step_i (1+ step_i))
)
(setq i (1+ i))
)
;; Генерация 3D-сетки единой скульптурной ладони и запястья
(setq grid_rows nil
n_seg 32)
(foreach item interp_sec
(setq pt_c  (nth 0 item)
u_c   (nth 1 item)
v_c   (nth 2 item)
th_b  (nth 3 item)
cup_d (nth 4 item))
(setq row_pts nil
j 0)
(while (< j n_seg)
(setq ang (* (/ (float j) (float n_seg)) two_pi)
cos_a (cos ang)
sin_a (sin ang))
;; (defun c:DONUTHAND ( / old_cmd old_osm old_dyn old_blip
pi_val two_pi
v-add v-sub v-scale v-len v-norm v-cross v-dot v-lerp
catmull-rom-pt calc-frame
make-truecolor-mesh make-swept-organ make-ellipsoid-mesh
make-nail-mesh make-capsule-sprinkle
build-donut-base build-icing-mesh build-all-sprinkles
build-sculpted-palm build-all-fingers
sprinkle_data)
​;; Сохранение и отключение системных привязок и эха для мгновенной генерации
(setq old_cmd (getvar "CMDECHO"))
(setq old_osm (getvar "OSMODE"))
(setq old_dyn (getvar "DYNMODE"))
(setq old_blip (getvar "BLIPMODE"))
​(setvar "CMDECHO" 0)
(setvar "OSMODE" 0)
(if old_dyn (setvar "DYNMODE" 0))
(if old_blip (setvar "BLIPMODE" 0))
​(setq pi_val 3.14159265358979323846)
(setq two_pi (* 2.0 pi_val))
​(princ "\n[1/5] Инициализация математического ядра 3D-скульптинга...")
​;; ==========================================================================
;; 1. БИБЛИОТЕКА ВЕКТОРНОЙ АЛГЕБРЫ И СПЛАЙНОВОЙ ИНТЕРПОЛЯЦИИ
;; ==========================================================================
​(defun v-add (a b) (mapcar '+ a b))
(defun v-sub (a b) (mapcar '- a b))
(defun v-scale (a s) (mapcar '(lambda (x) (* x s)) a))
(defun v-dot (a b) (apply '+ (mapcar '* a b)))
​(defun v-len (a)
(sqrt (apply '+ (mapcar '(lambda (x) (* x x)) a)))
)
​(defun v-norm (a / l)
(setq l (v-len a))
(if (> l 1e-8)
(v-scale a (/ 1.0 l))
'(0.0 0.0 1.0)
)
)
​(defun v-cross (a b)
(list
(- (* (nth 1 a) (nth 2 b)) (* (nth 2 a) (nth 1 b)))
(- (* (nth 2 a) (nth 0 b)) (* (nth 0 a) (nth 2 b)))
(- (* (nth 0 a) (nth 1 b)) (* (nth 1 a) (nth 0 b)))
)
)
​(defun v-lerp (a b t_param)
(v-add a (v-scale (v-sub b a) t_param))
)
​;; Гладкая интерполяция сплайном Катмулла-Рома по 4 точкам (t от 0.0 до 1.0)
(defun catmull-rom-pt (p0 p1 p2 p3 t_val / t2 t3 c0 c1 c2 c3)
(setq t2 (* t_val t_val)
t3 (* t2 t_val)
c0 (+ (* -0.5 t3) (* 1.0 t2) (* -0.5 t_val))
c1 (+ (*  1.5 t3) (* -2.5 t2) 1.0)
c2 (+ (* -1.5 t3) (* 2.0 t2) (* 0.5 t_val))
c3 (+ (*  0.5 t3) (* -0.5 t2)))
(v-add
(v-add (v-scale p0 c0) (v-scale p1 c1))
(v-add (v-scale p2 c2) (v-scale p3 c3))
)
)
​;; Вычисление локальной ортонормированной системы координат (T, N, B) вдоль кривой
(defun calc-frame (tan_vec up_hint / t_n n_vec b_vec)
(setq t_n (v-norm tan_vec))
(if (< (abs (v-dot t_n up_hint)) 0.92)
(setq b_vec (v-norm (v-cross t_n up_hint)))
(setq b_vec (v-norm (v-cross t_n '(1.0 0.0 0.0))))
)
(setq n_vec (v-norm (v-cross b_vec t_n)))
(list t_n n_vec b_vec)
)
​;; ==========================================================================
;; 2. ЯДРО ГЕНЕРАЦИИ 3D-СЕТОК С ПОДДЕРЖКОЙ TRUECOLOR (24-BIT RGB)
;; ==========================================================================
​;; Функция создания полигональной 3D-сетки напрямую в базу AutoCAD (entmake)
;; m_cnt - число рядов, n_cnt - число точек в ряду (до 256х256)
;; close_m / close_n - флаги замкнутости по U и V
;; aci_col - запасной индекс цвета, rgb_list - список (R G B) для TrueColor
(defun make-truecolor-mesh (pts_grid m_cnt n_cnt close_m close_n aci_col rgb_list
/ flag_bits true_col header_data row_pts pt_xyz vtx_data)
(setq flag_bits 16)
(if close_m (setq flag_bits (+ flag_bits 1)))
(if close_n (setq flag_bits (+ flag_bits 32)))
​(setq true_col (+ (lsh 1 24)
(lsh (nth 0 rgb_list) 16)
(lsh (nth 1 rgb_list) 8)
(nth 2 rgb_list)))
​(setq header_data
(list
'(0 . "POLYLINE")
'(100 . "AcDbEntity")
(cons 62 aci_col)
(cons 420 true_col)
'(100 . "AcDbPolygonMesh")
'(66 . 1)
'(10 0.0 0.0 0.0)
(cons 70 flag_bits)
(cons 71 m_cnt)
(cons 72 n_cnt)
)
)
(entmake header_data)
​(foreach row_pts pts_grid
(foreach pt_xyz row_pts
(setq vtx_data
(list
'(0 . "VERTEX")
'(100 . "AcDbEntity")
(cons 62 aci_col)
(cons 420 true_col)
'(100 . "AcDbVertex")
'(100 . "AcDbPolygonMeshVertex")
(cons 10 pt_xyz)
'(70 . 64)
)
)
(entmake vtx_data)
)
)
(entmake (list '(0 . "SEQEND") (cons 62 aci_col) (cons 420 true_col)))
)
​;; Универсальный генератор органической трубчатой формы с анатомическим профилем
;; ctrl_pts: список ключевых точек (X Y Z Rx Ry Bulge)
;; sub_steps: число промежуточных колец между соседними ключевыми точками
;; n_seg: число граней по окружности сечения
;; cap_start / cap_end: скругление начала и конца (фаланги, пальцы, капли)
(defun make-swept-organ (ctrl_pts sub_steps n_seg cap_start cap_end up_vec aci_col rgb_list
/ ext_pts num_ctrl spine_list i p0 p1 p2 p3 step_idx t_val
pt_c rx_c ry_c b_c total_rings idx pt_prev pt_next tan_v
frame_v n_v b_v grid_rows ring_item j ang cos_a sin_a
rad_x rad_y flat_bottom local_x local_y world_pt
first_sp last_sp tip_pt cap_ring k cap_t cap_ang)
​;; Дублируем крайние точки для сплайна Катмулла-Рома
(setq ext_pts (append (list (car ctrl_pts)) ctrl_pts (list (last ctrl_pts))))
(setq num_ctrl (length ctrl_pts))
(setq spine_list nil)
​(setq i 0)
(while (< i (1- num_ctrl))
(setq p0 (nth i ext_pts)
p1 (nth (1+ i) ext_pts)
p2 (nth (+ i 2) ext_pts)
p3 (nth (+ i 3) ext_pts))
(setq step_idx 0)
(while (< step_idx sub_steps)
(setq t_val (/ (float step_idx) (float sub_steps)))
(setq pt_c (catmull-rom-pt
(list (nth 0 p0) (nth 1 p0) (nth 2 p0))
(list (nth 0 p1) (nth 1 p1) (nth 2 p1))
(list (nth 0 p2) (nth 1 p2) (nth 2 p2))
(list (nth 0 p3) (nth 1 p3) (nth 2 p3))
t_val))
(setq rx_c (+ (nth 3 p1) (* (- (nth 3 p2) (nth 3 p1)) t_val)))
(setq ry_c (+ (nth 4 p1) (* (- (nth 4 p2) (nth 4 p1)) t_val)))
(setq b_c  (+ (nth 5 p1) (* (- (nth 5 p2) (nth 5 p1)) t_val)))
(setq spine_list (append spine_list (list (list pt_c rx_c ry_c b_c))))
(setq step_idx (1+ step_idx))
)
(setq i (1+ i))
)
;; Добавляем финальную точку
(setq p2 (last ctrl_pts))
(setq spine_list
(append spine_list
(list (list (list (nth 0 p2) (nth 1 p2) (nth 2 p2))
(nth 3 p2) (nth 4 p2) (nth 5 p2)))))
​(setq total_rings (length spine_list))
(setq grid_rows nil)
​;; Если нужно скругленное начало
(if cap_start
(progn
(setq first_sp (car spine_list))
(setq pt_c (nth 0 first_sp)
rx_c (nth 1 first_sp)
ry_c (nth 2 first_sp))
(setq tan_v (v-norm (v-sub (nth 0 (nth 1 spine_list)) pt_c)))
(setq frame_v (calc-frame tan_v up_vec)
n_v (nth 1 frame_v)
b_v (nth 2 frame_v))
(setq k 3)
(while (> k 0)
(setq cap_ang (* (/ (float k) 3.5) (* 0.5 pi_val)))
(setq cap_ring nil
j 0)
(while (< j n_seg)
(setq ang (* (/ (float j) (float n_seg)) two_pi)
cos_a (cos ang)
sin_a (sin ang))
(setq world_pt
(v-add
(v-sub pt_c (v-scale tan_v (* 0.65 rx_c (sin cap_ang))))
(v-add
(v-scale n_v (* rx_c (cos cap_ang) cos_a))
(v-scale b_v (* ry_c (cos cap_ang) sin_a))
)
)
)
(setq cap_ring (append cap_ring (list world_pt)))
(setq j (1+ j))
)
(setq grid_rows (append grid_rows (list cap_ring)))
(setq k (1- k))
)
)
)
​;; Построение основных колец вдоль хребта
(setq idx 0)
(while (< idx total_rings)
(setq ring_item (nth idx spine_list)
pt_c (nth 0 ring_item)
rx_c (nth 1 ring_item)
ry_c (nth 2 ring_item)
b_c  (nth 3 ring_item))
​(cond
((= idx 0)
(setq tan_v (v-sub (nth 0 (nth 1 spine_list)) pt_c)))
((= idx (1- total_rings))
(setq tan_v (v-sub pt_c (nth 0 (nth (- idx 1) spine_list)))))
(T
(setq tan_v (v-sub (nth 0 (nth (1+ idx) spine_list))
(nth 0 (nth (1- idx) spine_list)))))
)
​(setq frame_v (calc-frame tan_v up_vec)
n_v (nth 1 frame_v)
b_v (nth 2 frame_v))
​(setq cap_ring nil
j 0)
(while (< j n_seg)
(setq ang (* (/ (float j) (float n_seg)) two_pi)
cos_a (cos ang)
sin_a (sin ang))
;; Анатомическое профилирование: легкая полнота подушечки и плавность тыльной стороны
(setq flat_bottom (+ 1.0 (* b_c (sin ang)) (* -0.06 (cos (* 2.0 ang)))))
(setq local_x (* rx_c cos_a (+ 1.0 (* 0.05 (sin ang))))
local_y (* ry_c sin_a flat_bottom))
​(setq world_pt
(v-add pt_c
(v-add (v-scale n_v local_x)
(v-scale b_v local_y))))
(setq cap_ring (append cap_ring (list world_pt)))
(setq j (1+ j))
)
(setq grid_rows (append grid_rows (list cap_ring)))
(setq idx (1+ idx))
)
​;; Анатомический округлый кончик пальца (купол в 4 плавных шага)
(if cap_end
(progn
(setq last_sp (last spine_list))
(setq pt_c (nth 0 last_sp)
rx_c (nth 1 last_sp)
ry_c (nth 2 last_sp))
(setq tan_v (v-norm (v-sub pt_c (nth 0 (nth (- total_rings 2) spine_list)))))
(setq frame_v (calc-frame tan_v up_vec)
n_v (nth 1 frame_v)
b_v (nth 2 frame_v))
(setq k 1)
(while (<= k 4)
(setq cap_ang (* (/ (float k) 4.2) (* 0.5 pi_val)))
(setq cap_ring nil
j 0)
(while (< j n_seg)
(setq ang (* (/ (float j) (float n_seg)) two_pi)
cos_a (cos ang)
sin_a (sin ang))
(setq world_pt
(v-add
(v-add pt_c (v-scale tan_v (* 0.88 rx_c (sin cap_ang))))
(v-add
(v-scale n_v (* rx_c (cos cap_ang) cos_a))
(v-scale b_v (* ry_c (cos cap_ang) sin_a))
)
)
)
(setq cap_ring (append cap_ring (list world_pt)))
(setq j (1+ j))
)
(setq grid_rows (append grid_rows (list cap_ring)))
(setq k (1+ k))
)
)
)
​(make-truecolor-mesh grid_rows (length grid_rows) n_seg nil T aci_col rgb_list)
)
​;; Генератор гладкого ориентированного эллипсоида (для мышц ладони и подушечек)
(defun make-ellipsoid-mesh (center_pt axis_u axis_v axis_w m_seg n_seg aci_col rgb_list
/ grid_rows i j phi theta sin_p cos_p sin_t cos_t row_pts pt_w)
(setq grid_rows nil
i 0)
(while (< i m_seg)
(setq phi (* (/ (float i) (float (1- m_seg))) pi_val))
(if (= i 0) (setq phi 0.04))
(if (= i (1- m_seg)) (setq phi (- pi_val 0.04)))
(setq sin_p (sin phi)
cos_p (cos phi)
row_pts nil
j 0)
(while (< j n_seg)
(setq theta (* (/ (float j) (float n_seg)) two_pi)
sin_t (sin theta)
cos_t (cos theta))
(setq pt_w
(v-add center_pt
(v-add
(v-scale axis_u (* sin_p cos_t))
(v-add
(v-scale axis_v (* sin_p sin_t))
(v-scale axis_w cos_p)
)
)
)
)
(setq row_pts (append row_pts (list pt_w)))
(setq j (1+ j))
)
(setq grid_rows (append grid_rows (list row_pts)))
(setq i (1+ i))
)
(make-truecolor-mesh grid_rows m_seg n_seg nil T aci_col rgb_list)
)
​;; Генератор реалистичного 3D-ноготка с поперечной аркой и боковыми валиками
(defun make-nail-mesh (base_pt tip_pt normal_dir width_val len_val curve_h
/ dir_v side_v nrm_v m_rows n_cols i j u_t v_t
width_scale arch_z len_curve pt_nail grid_rows row_pts)
(setq dir_v (v-norm (v-sub tip_pt base_pt)))
(setq nrm_v (v-norm normal_dir))
(setq side_v (v-norm (v-cross dir_v nrm_v)))
(setq nrm_v (v-norm (v-cross side_v dir_v)))
​(setq m_rows 8
n_cols 9
grid_rows nil
i 0)
(while (< i m_rows)
(setq u_t (/ (float i) (float (1- m_rows))))
;; Закругление кутикулы и свободного края ногтя
(setq width_scale (- 1.0 (* 0.28 (expt (- (* 2.0 u_t) 0.9) 2))))
(setq len_curve (* 0.18 curve_h (sin (* u_t pi_val))))
(setq row_pts nil
j 0)
(while (< j n_cols)
(setq v_t (- (/ (float j) (float (1- n_cols))) 0.5))
;; Поперечный свод ногтя
(setq arch_z (* curve_h (cos (* v_t pi_val 0.92))))
(setq pt_nail
(v-add base_pt
(v-add
(v-scale dir_v (* u_t len_val))
(v-add
(v-scale side_v (* v_t width_val width_scale))
(v-scale nrm_v (+ arch_z len_curve))
)
)
)
)
(setq row_pts (append row_pts (list pt_nail)))
(setq j (1+ j))
)
(setq grid_rows (append grid_rows (list row_pts)))
(setq i (1+ i))
)
;; Нежно-розовый глянцевый оттенок ногтевой пластины
(make-truecolor-mesh grid_rows m_rows n_cols nil nil 9 '(255 224 222))
)
​;; ==========================================================================
;; 3. ПОСТРОЕНИЕ ПОНЧИКА, СВЕТЛОЙ ПОЛОСКИ И ВОЛНИСТОЙ ГЛАЗУРИ С КАПЛЯМИ
;; ==========================================================================
​(defun build-donut-base ( / m_tor n_tor i j u_ang v_ang cos_u sin_u cos_v sin_v
R_maj r_min flat_z r_eff x_p y_p z_p
grid_dough row_pts
grid_belt belt_rows v_belt)
(princ "\n[2/5] Моделирование пышного теста пончика и светлого пояска...")
(setq R_maj 54.0
r_min 26.5
m_tor 64
n_tor 36
grid_dough nil
i 0)
​(while (< i m_tor)
(setq u_ang (* (/ (float i) (float m_tor)) two_pi)
cos_u (cos u_ang)
sin_u (sin u_ang)
row_pts nil
j 0)
(while (< j n_tor)
(setq v_ang (* (/ (float j) (float n_tor)) two_pi)
cos_v (cos v_ang)
sin_v (sin v_ang))
;; Пышная приплюснутая форма настоящего доната с легкими неровностями выпечки
(setq r_eff (+ R_maj
(* r_min cos_v)
(* 0.45 (sin (* 5.0 u_ang)) (cos v_ang))))
(setq z_p (* r_min 0.84 sin_v))
(setq x_p (* r_eff cos_u)
y_p (* r_eff sin_u))
(setq row_pts (append row_pts (list (list x_p y_p z_p))))
(setq j (1+ j))
)
(setq grid_dough (append grid_dough (list row_pts)))
(setq i (1+ i))
)
;; Теплый золотисто-карамельный цвет обжаренного пончика
(make-truecolor-mesh grid_dough m_tor n_tor T T 30 '(232 138 48))
​;; Фирменная светлая полоска посередине боковины пончика (как на вашем фото!)
(setq grid_belt nil
belt_rows 7
i 0)
(while (< i m_tor)
(setq u_ang (* (/ (float i) (float m_tor)) two_pi)
cos_u (cos u_ang)
sin_u (sin u_ang)
row_pts nil
j 0)
(while (< j belt_rows)
(setq v_belt (* (- (/ (float j) (float (1- belt_rows))) 0.5) 0.28))
(setq r_eff (+ R_maj (* (+ r_min 0.22) (cos v_belt))))
(setq z_p (* r_min 0.84 (sin v_belt)))
(setq row_pts (append row_pts (list (list (* r_eff cos_u) (* r_eff sin_u) z_p))))
(setq j (1+ j))
)
(setq grid_belt (append grid_belt (list row_pts)))
(setq i (1+ i))
)
;; Нежно-сливочный цвет пояска теста
(make-truecolor-mesh grid_belt m_tor belt_rows T nil 51 '(249 194 128))
)
​(defun build-icing-mesh ( / m_ice n_ice i j u_ang t_v
R_maj r_min drip_wave crease_wave
v_start v_end v_ang cos_u sin_u cos_v sin_v
thick_offset lip_bulge inner_fold
r_curr r_eff x_p y_p z_p
grid_ice row_pts)
(princ "\n[3/5] Генерация глянцевой розовой глазури со складками и подтеками...")
(setq R_maj 54.0
r_min 26.5
m_ice 96
n_ice 32
grid_ice nil
i 0)
​(while (< i m_ice)
(setq u_ang (* (/ (float i) (float m_ice)) two_pi)
cos_u (cos u_ang)
sin_u (sin u_ang))
​;; Сложная гармоника красивых капель и волн глазури по внешнему краю (точь-в-точь как на фото)
(setq drip_wave
(+ (* 0.14 (sin (* 5.0 u_ang)))
(* 0.19 (cos (- (* 8.0 u_ang) 0.7)))
(* 0.11 (sin (+ (* 13.0 u_ang) 1.4)))
(* 0.06 (cos (* 21.0 u_ang)))
;; Выразительные капли на переднем плане между пальцами
(* 0.16 (exp (* -12.0 (expt (sin (* 0.5 (- u_ang 4.55))) 2))))
(* 0.14 (exp (* -14.0 (expt (sin (* 0.5 (- u_ang 5.18))) 2))))
(* 0.13 (exp (* -14.0 (expt (sin (* 0.5 (- u_ang 3.85))) 2))))
)
)
​;; Радиальные мягкие складочки глазури, сходящиеся к внутреннему отверстию пончика
(setq crease_wave
(+ (* 0.55 (sin (* 18.0 u_ang)))
(* 0.35 (cos (* 27.0 u_ang)))
)
)
​;; Глазурь идет от внешнего нижнего края (с волнами) через верх до внутренней дырочки
(setq v_start (- -0.14 drip_wave)
v_end   (+ pi_val 0.22)
row_pts nil
j 0)
​(while (< j n_ice)
(setq t_v (/ (float j) (float (1- n_ice))))
(setq v_ang (+ v_start (* t_v (- v_end v_start)))
cos_v (cos v_ang)
sin_v (sin v_ang))
​;; Пухлый бортик на самом краю капель глазури (эффект поверхностного натяжения)
(setq lip_bulge (* 1.35 (exp (* -28.0 (expt t_v 2)))))
;; Радиальные складки усиливаются ближе к отверстию пончика
(setq inner_fold (* crease_wave (expt (sin (* t_v 0.85 pi_val)) 2) (if (> t_v 0.45) 1.0 0.25)))
​(setq thick_offset (+ 1.65 lip_bulge (* 0.45 (sin (* t_v pi_val))) (* 0.35 inner_fold)))
(setq r_curr (+ r_min thick_offset))
​(setq r_eff (+ R_maj (* r_curr cos_v)))
(setq z_p (+ (* r_curr 0.85 sin_v) 0.55 (* 0.25 inner_fold)))
(setq x_p (* r_eff cos_u)
y_p (* r_eff sin_u))
​(setq row_pts (append row_pts (list (list x_p y_p z_p))))
(setq j (1+ j))
)
(setq grid_ice (append grid_ice (list row_pts)))
(setq i (1+ i))
)
;; Насыщенный клубнично-розовый цвет глазури
(make-truecolor-mesh grid_ice m_ice n_ice T nil 241 '(252 126 178))
)
​;; ==========================================================================
;; 4. ГЕНЕРАЦИЯ 88 КАПСУЛ РАЗНОЦВЕТНОЙ КОНДИТЕРСКОЙ ПОСЫПКИ
;; ==========================================================================
​(defun make-capsule-sprinkle (u_deg v_deg rot_deg col_id
/ u_rad v_rad rot_rad R_maj r_ice
cos_u sin_u cos_v sin_v
pt_surf nrm_surf tan_u tan_v dir_spr side_spr
spr_rad spr_hlen p_start p_end
aci_c rgb_c ctrl_spr)
(setq u_rad (* u_deg (/ pi_val 180.0))
v_rad (* v_deg (/ pi_val 180.0))
rot_rad (* rot_deg (/ pi_val 180.0))
R_maj 54.0
r_ice 28.4)
​(setq cos_u (cos u_rad) sin_u (sin u_rad)
cos_v (cos v_rad) sin_v (sin v_rad))
​;; Точка на поверхности глазури и локальная нормаль
(setq pt_surf
(list
(* (+ R_maj (* r_ice cos_v)) cos_u)
(* (+ R_maj (* r_ice cos_v)) sin_u)
(+ (* r_ice 0.85 sin_v) 0.65)
)
)
(setq nrm_surf (v-norm (list (* cos_v cos_u) (* cos_v sin_u) (/ sin_v 0.85))))
(setq tan_u (list (- sin_u) cos_u 0.0))
(setq tan_v (v-norm (v-cross nrm_surf tan_u)))
​;; Поворот посыпки в касательной плоскости глазури
(setq dir_spr (v-norm (v-add (v-scale tan_u (cos rot_rad))
(v-scale tan_v (sin rot_rad)))))
​(setq spr_rad 1.25
spr_hlen 2.35)
(setq pt_surf (v-add pt_surf (v-scale nrm_surf 0.55)))
(setq p_start (v-sub pt_surf (v-scale dir_spr spr_hlen))
p_end   (v-add pt_surf (v-scale dir_spr spr_hlen)))
​;; Цветовая палитра посыпки с вашего фото: белый, голубой, мятно-зеленый, оранжево-желтый, лавандовый, ярко-розовый
(cond
((= col_id 1) (setq aci_c 7   rgb_c '(252 252 255))) ;; Белый
((= col_id 2) (setq aci_c 140 rgb_c '(58 192 248)))  ;; Ярко-голубой
((= col_id 3) (setq aci_c 92  rgb_c '(82 218 142)))  ;; Мятно-зеленый
((= col_id 4) (setq aci_c 40  rgb_c '(255 182 54)))  ;; Желто-оранжевый
((= col_id 5) (setq aci_c 191 rgb_c '(196 138 242))) ;; Лавандово-фиолетовый
(T            (setq aci_c 230 rgb_c '(255 96 158)))  ;; Ярко-розовый
)
​(setq ctrl_spr
(list
(list (nth 0 p_start) (nth 1 p_start) (nth 2 p_start) spr_rad spr_rad 0.0)
(list (nth 0 pt_surf) (nth 1 pt_surf) (nth 2 pt_surf) spr_rad spr_rad 0.0)
(list (nth 0 p_end)   (nth 1 p_end)   (nth 2 p_end)   spr_rad spr_rad 0.0)
)
)
(make-swept-organ ctrl_spr 1 8 T T nrm_surf aci_c rgb_c)
)
​(defun build-all-sprinkles ( / s_list item)
(princ "\n[4/5] Раскладка 88 объемных капсул кондитерской посыпки...")
;; Таблица координат (U-угол, V-угол, Поворот, Цвет) для плотного и живописного покрытия
(setq s_list
'(
;; Передний склон (обращенный к зрителю и над пальцами)
(245 12 35 3)  (252 32 -20 1) (258 55 48 4)  (264 18 -65 3) (270 42 15 1)
(276 8  80 2)  (282 28 -35 6) (288 52 12 2)  (294 16 45 4)  (300 38 -50 1)
(306 5  25 2)  (312 30 -15 5) (318 58 60 1)  (324 22 -40 4) (330 44 30 3)
(336 12 -70 1) (342 36 18 2)  (348 62 -25 5) (354 20 55 4)  (238 26 -12 4)
(232 48 65 1)  (225 15 -45 6) (218 35 22 4)  (212 58 -30 3) (205 22 40 1)
;; Внешний гребень и макушка пончика
(0   45 -20 3) (8   25 50 1)  (16  68 -35 5) (24  38 15 4)  (32  82 -60 2)
(40  52 30 1)  (48  22 -15 6) (56  72 45 3)  (64  42 -50 4) (72  88 20 1)
(80  58 -25 2) (88  30 65 5)  (96  75 -40 4) (104 48 12 3)  (112 85 -18 1)
(120 55 35 2)  (128 28 -55 4) (136 72 25 5)  (144 45 -30 3) (152 82 50 1)
(160 52 -15 4) (168 25 40 2)  (176 68 -45 5) (184 42 18 1)  (192 78 -22 3)
(200 48 60 2)  (210 82 -35 4) (222 72 15 1)  (235 85 -50 3) (248 78 28 2)
(260 88 -15 5) (274 76 42 4)  (286 86 -30 1) (298 74 55 3)  (310 84 -20 6)
(322 76 35 2)  (335 88 -45 4) (346 75 15 1)
;; Внутренний склон к отверстию пончика
(15  118 25 4) (35  128 -40 2) (55  115 60 1) (75  132 -15 3) (95  120 35 5)
(115 135 -50 4)(135 118 20 2)  (155 130 -30 1)(175 115 45 3)  (195 128 -25 6)
(215 118 55 2) (235 132 -40 5) (255 122 15 3) (275 135 -60 4) (295 118 30 2)
(315 130 -20 5)(335 116 48 1)  (355 128 -35 4)
;; Дополнительные акценты на передних волнах глазури
(266 2   10 3) (290 4   -25 1) (316 8   40 2) (242 6   -15 4) (226 8   30 1)
(278 64  -55 5)(250 62  20 2)
)
)
(foreach item s_list
(make-capsule-sprinkle (nth 0 item) (nth 1 item) (nth 2 item) (nth 3 item))
)
)
​;; ==========================================================================
;; 5. АНАТОМИЧЕСКИЙ СКУЛЬПТИНГ ЖЕНСКОЙ РУКИ, ЛАДОНИ, ПАЛЬЦЕВ И НОГТЕЙ
;; ==========================================================================
​(defun build-sculpted-palm ( / skin_rgb skin_aci palm_spine)
(princ "\n[5/5] Анатомический скульптинг изящной руки, фаланг пальцев и ногтей...")
;; Естественный теплый персиково-розовый оттенок кожи (TrueColor)
(setq skin_rgb '(246 184 156)
skin_aci 41)
​;; 1. Главный ствол от предплечья через изящное запястье к широкой чаше ладони
(setq palm_spine
'(
;; Предплечье уходит в правый нижний угол кадра (точно по ракурсу фото)
(78.0 -14.0 -122.0  24.0 18.0  0.02)
(60.0 -10.0 -96.0   22.5 16.5  0.04)
;; Анатомическое сужение в области запястья
(44.0 -7.0  -72.0   21.5 15.5  0.06)
;; Расширение основания ладони и пятки ладони
(28.0 -10.0 -52.0   28.5 18.5  0.10)
;; Центральная чаша ладони, поддерживающая пончик снизу
(8.0  -13.0 -37.0   35.0 17.5  0.12)
;; Пястная область (основание пальцев)
(-15.0 -11.0 -27.0  34.5 14.5  0.08)
(-34.0 -5.0  -20.0  26.0 11.5  0.05)
)
)
(make-swept-organ palm_spine 6 28 nil T '(0.25 -0.85 0.45) skin_aci skin_rgb)
​;; 2. Возвышение большого пальца (тенар — мягкая округлая мышца на переднем плане справа)
(make-ellipsoid-mesh
'(15.0 -26.0 -40.0)
'(24.0 -8.0 12.0)
'(6.0 15.0 5.0)
'(-8.0 -5.0 18.0)
16 24 skin_aci skin_rgb
)
​;; 3. Возвышение мизинца (гипотенар — внешний край ладони и плавный переход к запястью)
(make-ellipsoid-mesh
'(22.0 8.0 -46.0)
'(26.0 8.0 16.0)
'(-5.0 14.0 -3.0)
'(-9.0 3.0 16.0)
14 20 skin_aci skin_rgb
)
​;; 4. Мягкая кожная складочка у основания большого пальца (как на фото справа внизу от пончика)
(make-ellipsoid-mesh
'(26.0 -21.0 -46.0)
'(12.0 -5.0 9.0)
'(5.0 9.0 2.0)
'(-5.0 -3.0 9.0)
12 18 skin_aci skin_rgb
)
)
​(defun build-all-fingers ( / skin_rgb skin_aci
f1_thumb f2_index f3_middle f4_ring f5_pinky)
(setq skin_rgb '(246 184 156)
skin_aci 41)
​;; ------------------------------------------------------------------------
;; ПАЛЕЦ 1: БОЛЬШОЙ ПАЛЕЦ (на переднем плане по центру-справа, обхватывает пончик)
;; ------------------------------------------------------------------------
(setq f1_thumb
'(
(16.0  -28.0 -42.0   12.8 11.5  0.08) ;; Выход из тенара
(2.0   -42.0 -36.0   11.2 10.2  0.10) ;; Пястно-фаланговый изгиб
(-11.0 -56.0 -25.0   10.2  9.4  0.12) ;; Межфаланговый сустав (выступающий сгиб)
(-10.0 -66.0  -9.0    9.5  8.6  0.10) ;; Дистальная фаланга поднимается к глазури
(-6.5  -70.5   6.5    8.6  7.4  0.06) ;; Кончик большого пальца у капли глазури
)
)
(make-swept-organ f1_thumb 6 24 T T '(0.15 -0.92 -0.35) skin_aci skin_rgb)
​;; 3D-ноготок большого пальца (развернут влево-к-зрителю, точно как на фото)
(make-nail-mesh
'(-9.2 -67.5 -2.5)
'(-6.0 -71.2  9.2)
'(-0.42 -0.88 0.22)
10.8 12.2 1.8
)
​;; ------------------------------------------------------------------------
;; ПАЛЕЦ 2: УКАЗАТЕЛЬНЫЙ ПАЛЕЦ (главный центральный палец слева от большого)
;; ------------------------------------------------------------------------
(setq f2_index
'(
(-16.0 -19.0 -29.0   10.5  9.8  0.06) ;; Основание в ладони
(-33.0 -36.0 -24.0    9.6  9.2  0.10) ;; Проксимальная фаланга
(-45.0 -53.0 -10.0    9.1  8.6  0.12) ;; Проксимальный сустав
(-43.0 -59.0  10.0    8.4  7.8  0.10) ;; Средняя фаланга прижата к боку пончика
(-38.0 -56.0  26.5    7.5  6.6  0.06) ;; Кончик на уровне розовой глазури
)
)
(make-swept-organ f2_index 6 24 T T '(-0.55 -0.80 0.20) skin_aci skin_rgb)
​;; 3D-ноготок указательного пальца
(make-nail-mesh
'(-41.2 -59.5 16.5)
'(-37.2 -56.2 29.2)
'(-0.52 -0.82 0.24)
9.4 11.8 1.6
)
​;; ------------------------------------------------------------------------
;; ПАЛЕЦ 3: СРЕДНИЙ ПАЛЕЦ (самый высокий палец слева, поддерживает край глазури)
;; ------------------------------------------------------------------------
(setq f3_middle
'(
(-28.0  -7.0 -24.0   10.6  9.8  0.06) ;; Основание
(-50.0 -18.0 -18.0    9.6  9.0  0.10) ;; Проксимальная фаланга
(-66.0 -31.0  -3.0    9.0  8.5  0.12) ;; Суставной сгиб
(-67.0 -37.0  16.0    8.3  7.6  0.10) ;; Средняя фаланга
(-61.0 -35.0  33.0    7.4  6.4  0.06) ;; Кончик у верхнего края розовой глазури
)
)
(make-swept-organ f3_middle 6 24 T T '(-0.78 -0.58 0.22) skin_aci skin_rgb)
​;; 3D-ноготок среднего пальца
(make-nail-mesh
'(-65.5 -37.8 22.5)
'(-60.2 -35.2 35.5)
'(-0.68 -0.68 0.26)
9.2 11.6 1.5
)
​;; ------------------------------------------------------------------------
;; ПАЛЕЦ 4: БЕЗЫМЯННЫЙ ПАЛЕЦ (изящно выглядывает слева за средним пальцем)
;; ------------------------------------------------------------------------
(setq f4_ring
'(
(-34.0   6.0 -20.0    9.8  9.0  0.06) ;; Основание
(-56.0   0.0 -13.0    8.8  8.2  0.10) ;; Проксимальная фаланга
(-73.0 -10.0   2.0    8.3  7.8  0.12) ;; Суставной сгиб
(-76.0 -16.0  19.0    7.6  7.0  0.08) ;; Средняя фаланга
(-71.0 -16.0  33.5    6.8  5.9  0.05) ;; Кончик у левого края пончика
)
)
(make-swept-organ f4_ring 6 22 T T '(-0.88 -0.42 0.22) skin_aci skin_rgb)
​;; 3D-ноготок безымянного пальца
(make-nail-mesh
'(-75.2 -17.2 24.5)
'(-70.5 -16.5 35.8)
'(-0.78 -0.58 0.24)
8.2 10.5 1.4
)
​;; ------------------------------------------------------------------------
;; ПАЛЕЦ 5: МИЗИНЕЦ (аккуратная поддержка сзади-слева для полноты 3D-сцены)
;; ------------------------------------------------------------------------
(setq f5_pinky
'(
(-35.0  18.0 -17.0    8.5  7.8  0.05)
(-54.0  18.0  -9.0    7.6  7.0  0.08)
(-68.0  12.0   4.0    7.0  6.5  0.10)
(-71.0   7.0  17.0    6.4  5.8  0.08)
(-67.0   5.0  27.5    5.6  5.0  0.05)
)
)
(make-swept-organ f5_pinky 5 20 T T '(-0.92 -0.25 0.30) skin_aci skin_rgb)
)
​;; ==========================================================================
;; 6. ЗАПУСК СБОРКИ СЦЕНЫ И НАСТРОЙКА КАМЕРЫ И РЕНДЕРА AUTOCAD 2020
;; ==========================================================================
​(build-donut-base)
(build-icing-mesh)
(build-all-sprinkles)
(build-sculpted-palm)
(build-all-fingers)
​;; Настройка ракурса камеры точно как на референсном изображении
;; и включение гладкого реалистичного рендера БЕЗ черных каркасных линий
(setvar "DISPSILH" 1)
(command "_.VPOINT" "non" '(-0.78 -1.92 0.76))
(command ".VSCURRENT" "R")
;; Отключаем отображение ребер полигональной сетки в стиле Realistic, чтобы поверхность была идеально гладкой
(vl-catch-all-apply 'setvar (list "VSEDGES" 0))
(command ".ZOOM" "E")
(command ".ZOOM" "0.92x")
​;; Восстановление системных настроек пользователя
(setvar "OSMODE" old_osm)
(if old_dyn (setvar "DYNMODE" old_dyn))
(if old_blip (setvar "BLIPMODE" old_blip))
(setvar "CMDECHO" old_cmd)
​(princ "\n==================================================================")
(princ "\n[ГОТОВО!] Высокополигональная 3D-модель руки с пончиком построена!")
(princ "\nЗажмите Shift + Колесико мыши, чтобы покрутить модель в 3D.")
(princ "\n==================================================================")
(princ)
)
​;; Автоматический запуск построения сразу после вставки или загрузки файла:
(c:DONUTHAND)