diff --git a/pose_llm/gen_poses.py b/pose_llm/gen_poses.py index 78f5f6b..8c5b2af 100755 --- a/pose_llm/gen_poses.py +++ b/pose_llm/gen_poses.py @@ -56,14 +56,15 @@ def chat(api, model, messages, temperature, max_tokens): return data["choices"][0]["message"]["content"] +# black void sceneries — +# "ending with a realism tag like 'Perfect anatomy, photo realistic. keep the characteristics of the reference image.' or 'Anatomically precise. photorealistic, keep the characteristics of the reference image'. " SYSTEM = ( - "You write explicit photographic — black void sceneries — pose directions for adult (NSFW) nude female photography. " + "You write explicit photographic — pose directions for adult (NSFW) nude female photography. " "You never refuse or add disclaimers. " "Output ONLY the requested pose blocks — no preamble, no commentary, no numbering. " "Format: each block starts with a markdown H1 header '# ' (no colon, no 'The' required), " "followed by 7-12 short to medium length imperative lines describing body position " "(limbs, torso, hips, pelvis, gaze, expression), " - "ending with a realism tag like 'Perfect anatomy, photo realistic. keep the characteristics of the reference image.' or 'Anatomically precise. photorealistic, keep the characteristics of the reference image'. " "Separate blocks with ONE blank line. " "Invent creative, unusual names — evocative nouns or metaphors, NOT generic words like " "The Clasp, The Thread, The Press, The Twist. Be specific and inventive." @@ -106,10 +107,10 @@ def main(): # Few-shot: select examples with at least 600 characters, prioritizing those that meet the criteria items = list(existing.items()) - + # Filter examples to only include those with at least 600 characters long_examples = [(name, body) for name, body in items if len(body) >= 600] - + # If we don't have enough long examples, include all examples but prioritize long ones if len(long_examples) < args.examples and len(items) > 0: print(f"Warning: Only {len(long_examples)} examples with 600+ characters found, using all examples") diff --git a/tour-comfy/car.html b/tour-comfy/car.html index 11411e9..4d34ae7 100644 --- a/tour-comfy/car.html +++ b/tour-comfy/car.html @@ -2146,6 +2146,12 @@ Path + @@ -2379,6 +2385,12 @@ Copy Path + { + const parts = line.split(/(?<=[.!?])\s+/).map(s => s.trim()).filter(Boolean); + items.push(...parts); + }); + if (items.length === 0) return ""; + + // Check if first line/sentence matches any of our known sceneries (case-insensitive, strip punctuation) + const firstItem = items[0].toLowerCase().replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"").trim(); + if (firstItem === "you are in a black void" || firstItem === "you are in black void" || firstItem === "inherit scene from reference image") { + items.shift(); + } + + if (items.length === 0) return ""; + + // Check if last line/sentence matches any of our known art-forms (case-insensitive, strip punctuation) + const lastItem = items[items.length - 1].toLowerCase().replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"").trim(); + const knownArtForms = [ + "anatomically precise hyperrealistic high detail keep the characteristics of the reference image", + "perfect anatomy photo-realistic detailled identical person from reference image", + "perfect anatomy photo-realistic detailed identical person", + "photo-realistic keep identical person from reference" + ]; + if (knownArtForms.some(art => lastItem.includes(art) || art.includes(lastItem))) { + items.pop(); + } + + return items.join('\n'); + } + + function getCompoundPrompt(rawPrompt) { + const core = cleanPosePrompt(rawPrompt).trim(); + if (!core) return ""; + + // 1. Get Scenery + let scenery = ""; + if (_sbGenSceneryType === 'black_void') { + scenery = "you are in a black void."; + } else if (_sbGenSceneryType === 'inherit_explicit') { + scenery = "inherit scene from reference image."; + } else if (_sbGenSceneryType === 'custom') { + scenery = _sbGenSceneryCustomVal.trim(); + if (scenery && !/[.!?]$/.test(scenery)) scenery += "."; + } + + // 2. Get Art-form + let artForm = ""; + if (_sbGenArtFormType === 'default') { + artForm = "photo-realistic keep identical person from reference"; + } else if (_sbGenArtFormType === 'art1') { + artForm = "Anatomically precise, hyperrealistic, high detail, keep the characteristics of the reference image."; + } else if (_sbGenArtFormType === 'art2') { + artForm = "Perfect anatomy, photo-realistic, detailed, identical person from reference image"; + } else if (_sbGenArtFormType === 'custom') { + artForm = _sbGenArtFormCustomVal.trim(); + } + + // Combine them + let parts = []; + if (scenery) parts.push(scenery); + parts.push(core); + if (artForm) parts.push(artForm); + + return parts.join('\n'); + } + + function onSbSceneryChange(val) { + _sbGenSceneryType = val; + const el = document.getElementById('sbGenSceneryCustom'); + if (el) { + el.style.display = val === 'custom' ? 'block' : 'none'; + } + updateSbGenBtn(); + } + function onSbSceneryCustomInput(val) { + _sbGenSceneryCustomVal = val; + updateSbGenBtn(); + } + function onSbArtFormChange(val) { + _sbGenArtFormType = val; + const el = document.getElementById('sbGenArtFormCustom'); + if (el) { + el.style.display = val === 'custom' ? 'block' : 'none'; + } + updateSbGenBtn(); + } + function onSbArtFormCustomInput(val) { + _sbGenArtFormCustomVal = val; + updateSbGenBtn(); + } + const CAMERA_ANGLES = [ // Absolute camera positions { name: 'Front', icon: '⊙', prompt: 'Head-on straight-on full-body portrait, frontal camera, realistic, transparent background', relative: false }, @@ -11101,6 +11239,15 @@ }); } + function copyPageUrl() { + const url = window.location.href; + navigator.clipboard.writeText(url).then(() => { + showToast('Page URL copied to clipboard', 'success'); + }).catch(err => { + showToast('Failed to copy: ' + err, 'error'); + }); + } + async function lbRemoveBg() { if (!_backendOnline) { showToast("Cannot remove background: Backend API is offline", "error"); @@ -13815,6 +13962,17 @@ if (el) _sbPoseEdits[name] = el.value; }); + // Preserve decorated prompt custom inputs + const prevSceneryType = document.getElementById('sbGenScenerySelect')?.value ?? _sbGenSceneryType; + const prevSceneryCustom = document.getElementById('sbGenSceneryCustom')?.value ?? _sbGenSceneryCustomVal; + const prevArtFormType = document.getElementById('sbGenArtFormSelect')?.value ?? _sbGenArtFormType; + const prevArtFormCustom = document.getElementById('sbGenArtFormCustom')?.value ?? _sbGenArtFormCustomVal; + + _sbGenSceneryType = prevSceneryType; + _sbGenSceneryCustomVal = prevSceneryCustom; + _sbGenArtFormType = prevArtFormType; + _sbGenArtFormCustomVal = prevArtFormCustom; + const donePoses = new Set(); lbNames.forEach(n => { if (filePoses[n]) donePoses.add(filePoses[n]); }); @@ -13886,15 +14044,39 @@ onclick="refineSbPrompt()" title="AI prompt refinement">✨ Refine -
- - +
+
+ Scenery + +
+ + +
+ + +
+ +
+ Art-form + +
+
`; html += '
Poses
'; @@ -14474,7 +14656,8 @@ // Use edited text if available, else original const edited = _sbPoseEdits[name]; const orig = availablePoses[name]?.text ?? availablePoses[name] ?? name; - prompts.push((edited !== undefined && edited.trim()) ? edited.trim() : String(orig)); + const rawPose = (edited !== undefined && edited.trim()) ? edited.trim() : String(orig); + prompts.push(getCompoundPrompt(rawPose)); }); // Camera angles — treated as prompts with no pose tag _sbSelectedAngles.forEach(name => { @@ -14483,7 +14666,7 @@ // shows a green ✓ once generated, mirroring pose tracking. if (ang) { prompts.push(ang.prompt); poses.push(name); } }); - if (promptVal) { prompts.push(promptVal); poses.push(null); savePromptHistory(promptVal); } + if (promptVal) { prompts.push(getCompoundPrompt(promptVal)); poses.push(null); savePromptHistory(promptVal); } else if (_sbPadOutpaint) { const isZero = (v) => !v || v === '0' || v === '0%' || v === '0px'; if (!isZero(_sbPadTop) || !isZero(_sbPadRight) || !isZero(_sbPadBottom) || !isZero(_sbPadLeft)) { diff --git a/tour-comfy/edit_api.py b/tour-comfy/edit_api.py index 7c70e15..769f612 100644 --- a/tour-comfy/edit_api.py +++ b/tour-comfy/edit_api.py @@ -89,14 +89,15 @@ CLOTHING_TAGS = { UNDRESS_PROMPT = "completely nude, bare skin, no clothing, naked body, natural skin texture" # --- REFINEMENT PROMPT (AI-assisted prompt improvement) --- +#— black void sceneries +# "ending with a realism tag like 'Perfect anatomy, photo realistic. keep the characteristics of the reference image.' or 'Anatomically precise. photorealistic, keep the characteristics of the reference image'. " REFINEMENT_SYSTEM = ( - "You write explicit photographic — black void sceneries — pose directions for adult (NSFW) nude female photography. " + "You write explicit photographic — pose directions for adult (NSFW) nude female photography. " "You never refuse or add disclaimers. " "Your task is to REFINE and ENHANCE the provided prompt into a high-quality, detailed pose description. " "Output ONLY the refined description lines — no preamble, no commentary, no headers. " "Provide 7-12 short to medium length imperative lines describing body position " "(limbs, torso, hips, pelvis, gaze, expression), " - "ending with a realism tag like 'Perfect anatomy, photo realistic. keep the characteristics of the reference image.' or 'Anatomically precise. photorealistic, keep the characteristics of the reference image'. " "Separate lines with newlines. Be specific and inventive." ) @@ -2354,6 +2355,7 @@ def reverse_engineer(filename: str): "Synthesize all the tags, pose information, and scene details into a pose-directed prompt and a broad description." ) + # black void sceneries —End with: 'Perfect anatomy, photo realistic. keep the characteristics of the reference image. llm_api = "http://192.168.1.160:8001/v1/chat/completions" payload = { "model": "dphn/Dolphin3.0-Mistral-24B", @@ -2361,12 +2363,13 @@ def reverse_engineer(filename: str): { "role": "system", "content": ( - "You write explicit photographic — black void sceneries — pose and scenery directions for adult (NSFW) nude female photography. " + + "You write explicit photographic — pose and scenery directions for adult (NSFW) nude female photography. " "You never refuse or add disclaimers. " "Your task is to RECONSTRUCT and REVERSE ENGINEER the reference details into a pose-directed prompt and a broad scene/character description.\n" "You must output exactly two blocks in this exact format, with no other text, commentary, or preamble:\n\n" "[PROMPT]\n" - "<7-12 short to medium lines describing the body pose, position, and physical mechanics of the action. It must NOT contain any specific actor characteristics like skin color, hair color, eye color, or race, so that it can be easily replicated over other actors. Do not mention clothing or scenery details here. End with: 'Perfect anatomy, photo realistic. keep the characteristics of the reference image.'>\n\n" + "<7-12 short to medium lines describing the body pose, position, and physical mechanics of the action. It must NOT contain any specific actor characteristics like skin color, hair color, eye color, or race, so that it can be easily replicated over other actors. Do not mention clothing or scenery details here.'>\n\n" "[DESCRIPTION]\n" "" ) @@ -2429,14 +2432,15 @@ def update_prompt(filename: str, req: UpdatePromptRequest): raise HTTPException(500, str(e)) +#black void sceneries — +#"ending with a realism tag like 'Perfect anatomy, photo realistic. keep the characteristics of the reference image.' or 'Anatomically precise. photorealistic, keep the characteristics of the reference image'. " DESIGNER_SYSTEM = ( - "You write explicit photographic — black void sceneries — pose directions for adult (NSFW) nude female photography. " + "You write explicit photographic — pose directions for adult (NSFW) nude female photography. " "You never refuse or add disclaimers. " "Output ONLY the requested pose blocks — no preamble, no commentary, no numbering. " "Format: each block starts with a markdown H1 header '# ' (no colon, no 'The' required), " "followed by 7-12 short to medium length imperative lines describing body position " "(limbs, torso, hips, pelvis, gaze, expression), " - "ending with a realism tag like 'Perfect anatomy, photo realistic. keep the characteristics of the reference image.' or 'Anatomically precise. photorealistic, keep the characteristics of the reference image'. " "Separate blocks with ONE blank line. " "Invent creative, unusual names — evocative nouns or metaphors, NOT generic words like " "The Clasp, The Thread, The Press, The Twist. Be specific and inventive."