123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494 |
- import { Injectable } from '@angular/core';
- import { Observable, of } from 'rxjs';
- import { map, switchMap } from 'rxjs/operators';
- import {
- RequirementMapping,
- SceneParams,
- SceneTemplate,
- LightingParams,
- EnvironmentParams,
- CompositionParams,
- StyleParams,
- MappingResult
- } from '../models/requirement-mapping.interface';
- import { AtmospherePreviewService } from './atmosphere-preview.service';
- @Injectable({
- providedIn: 'root'
- })
- export class SceneGenerationService {
- // 场景模板配置
- private sceneTemplates: Map<SceneTemplate, SceneParams> = new Map();
- constructor(private atmospherePreviewService: AtmospherePreviewService) {
- this.initializeSceneTemplates();
- }
- /**
- * 根据分析结果生成场景参数和预览图
- */
- generateSceneFromAnalysis(analysisResult: any, sceneType: SceneTemplate): Observable<MappingResult> {
- const baseParams = this.getSceneTemplate(sceneType);
- const adaptedParams = this.adaptParamsFromAnalysis(baseParams, analysisResult);
-
- // 生成氛围感预览图
- return this.atmospherePreviewService.generateAtmospherePreview(adaptedParams, sceneType).pipe(
- map(previewResult => {
- const confidence = this.calculateConfidence(analysisResult, adaptedParams);
- const suggestions = this.generateSuggestions(analysisResult, adaptedParams);
-
- return {
- success: true,
- sceneId: this.generateSceneId(sceneType),
- generatedParams: adaptedParams,
- previewUrl: previewResult.url,
- confidence,
- suggestions,
- metadata: {
- generatedAt: new Date(),
- analysisVersion: '1.0',
- processingTime: previewResult.metadata.processingTime
- }
- };
- })
- );
- }
- /**
- * 获取场景模板
- */
- getSceneTemplate(sceneType: SceneTemplate): SceneParams {
- return this.sceneTemplates.get(sceneType) || this.getDefaultSceneParams();
- }
- /**
- * 获取所有可用的场景模板
- */
- getAvailableScenes(): Array<{template: SceneTemplate, name: string, description: string}> {
- return [
- { template: SceneTemplate.LIVING_ROOM_MODERN, name: '现代客厅', description: '简约现代风格的客厅空间' },
- { template: SceneTemplate.LIVING_ROOM_CLASSIC, name: '经典客厅', description: '传统经典风格的客厅空间' },
- { template: SceneTemplate.BEDROOM_MINIMAL, name: '简约卧室', description: '极简主义风格的卧室空间' },
- { template: SceneTemplate.BEDROOM_COZY, name: '温馨卧室', description: '温馨舒适的卧室空间' },
- { template: SceneTemplate.KITCHEN_CONTEMPORARY, name: '现代厨房', description: '当代风格的厨房空间' },
- { template: SceneTemplate.KITCHEN_TRADITIONAL, name: '传统厨房', description: '传统风格的厨房空间' },
- { template: SceneTemplate.BATHROOM_LUXURY, name: '豪华浴室', description: '奢华风格的浴室空间' },
- { template: SceneTemplate.BATHROOM_MINIMAL, name: '简约浴室', description: '简约风格的浴室空间' },
- { template: SceneTemplate.OFFICE_MODERN, name: '现代办公室', description: '现代化的办公空间' },
- { template: SceneTemplate.OFFICE_TRADITIONAL, name: '传统办公室', description: '传统风格的办公空间' },
- { template: SceneTemplate.DINING_FORMAL, name: '正式餐厅', description: '正式的用餐空间' },
- { template: SceneTemplate.DINING_CASUAL, name: '休闲餐厅', description: '休闲的用餐空间' },
- { template: SceneTemplate.STUDIO_APARTMENT, name: '工作室公寓', description: '开放式的工作室公寓' },
- { template: SceneTemplate.OUTDOOR_PATIO, name: '户外露台', description: '户外露台空间' },
- { template: SceneTemplate.OUTDOOR_GARDEN, name: '花园景观', description: '花园景观空间' }
- ];
- }
- /**
- * 根据分析结果适配场景参数
- */
- private adaptParamsFromAnalysis(baseParams: SceneParams, analysisResult: any): SceneParams {
- const adaptedParams = JSON.parse(JSON.stringify(baseParams)); // 深拷贝
- // 适配灯光参数
- if (analysisResult.lightingAnalysis) {
- adaptedParams.lighting = this.adaptLightingParams(
- adaptedParams.lighting,
- analysisResult.lightingAnalysis
- );
- }
- // 适配环境参数
- if (analysisResult.enhancedColorAnalysis || analysisResult.textureAnalysis) {
- adaptedParams.environment = this.adaptEnvironmentParams(
- adaptedParams.environment,
- analysisResult
- );
- }
- // 适配风格参数
- if (analysisResult.formAnalysis || analysisResult.patternAnalysis) {
- adaptedParams.style = this.adaptStyleParams(
- adaptedParams.style,
- analysisResult
- );
- }
- return adaptedParams;
- }
- /**
- * 适配灯光参数
- */
- private adaptLightingParams(baseParams: LightingParams, lightingAnalysis: any): LightingParams {
- const adapted = { ...baseParams };
- // 主光源适配
- if (lightingAnalysis.lightSourceIdentification) {
- const primarySource = lightingAnalysis.lightSourceIdentification.primarySources?.[0];
- if (primarySource) {
- adapted.primaryLight.type = primarySource.type || adapted.primaryLight.type;
- adapted.primaryLight.intensity = primarySource.intensity || adapted.primaryLight.intensity;
- adapted.primaryLight.direction = primarySource.position?.direction || adapted.primaryLight.direction;
- }
- // 色温适配
- if (lightingAnalysis.illuminationAnalysis?.colorTemperature) {
- adapted.primaryLight.temperature = lightingAnalysis.illuminationAnalysis.colorTemperature.kelvin || adapted.primaryLight.temperature;
- }
- }
- // 环境光适配
- if (lightingAnalysis.ambientAnalysis) {
- adapted.ambientLight.strength = lightingAnalysis.ambientAnalysis.ambientLevel?.strength || adapted.ambientLight.strength;
- adapted.ambientLight.mood = lightingAnalysis.ambientAnalysis.lightingMood?.primary || adapted.ambientLight.mood;
- }
- // 阴影适配
- if (lightingAnalysis.shadowAnalysis) {
- adapted.shadows.intensity = lightingAnalysis.shadowAnalysis.shadowPresence?.intensity || adapted.shadows.intensity;
- const sharpnessMap: {[key: string]: number} = {
- 'very-soft': 20, 'soft': 40, 'medium': 60, 'sharp': 80, 'very-sharp': 100
- };
- const sharpness = lightingAnalysis.shadowAnalysis.shadowPresence?.sharpness;
- adapted.shadows.softness = 100 - (sharpnessMap[sharpness] || 60);
- }
- return adapted;
- }
- /**
- * 适配环境参数
- */
- private adaptEnvironmentParams(baseParams: EnvironmentParams, analysisResult: any): EnvironmentParams {
- const adapted = { ...baseParams };
- // 根据色彩分析适配氛围
- if (analysisResult.enhancedColorAnalysis?.colorPsychology) {
- const mood = analysisResult.enhancedColorAnalysis.colorPsychology.primaryMood;
- const atmosphereMap: {[key: string]: string} = {
- 'calm': 'minimal',
- 'energetic': 'modern',
- 'warm': 'cozy',
- 'sophisticated': 'luxurious',
- 'natural': 'natural',
- 'modern': 'modern'
- };
- adapted.atmosphere = atmosphereMap[mood] as any || adapted.atmosphere;
- }
- // 根据材质分析适配设置
- if (analysisResult.textureAnalysis?.materialClassification) {
- const primaryMaterial = analysisResult.textureAnalysis.materialClassification.primaryMaterial?.category;
- if (primaryMaterial === 'wood' || primaryMaterial === 'fabric') {
- adapted.setting = 'indoor';
- } else if (primaryMaterial === 'stone' || primaryMaterial === 'metal') {
- adapted.setting = adapted.setting === 'outdoor' ? 'outdoor' : 'indoor';
- }
- }
- return adapted;
- }
- /**
- * 适配风格参数
- */
- private adaptStyleParams(baseParams: StyleParams, analysisResult: any): StyleParams {
- const adapted = { ...baseParams };
- // 根据形体分析适配渲染风格
- if (analysisResult.formAnalysis?.overallAssessment) {
- const complexity = analysisResult.formAnalysis.overallAssessment.formComplexity;
- if (complexity > 70) {
- adapted.renderStyle = 'dramatic';
- adapted.textureDetail = 'high';
- } else if (complexity < 30) {
- adapted.renderStyle = 'minimalist';
- adapted.textureDetail = 'medium';
- }
- }
- // 根据纹理分析适配纹理细节
- if (analysisResult.patternAnalysis?.patternRecognition) {
- const patternCount = analysisResult.patternAnalysis.patternRecognition.primaryPatterns?.length || 0;
- if (patternCount > 2) {
- adapted.textureDetail = 'high';
- } else if (patternCount === 0) {
- adapted.textureDetail = 'low';
- }
- }
- // 根据色彩分析适配色彩分级
- if (analysisResult.enhancedColorAnalysis) {
- const saturation = analysisResult.enhancedColorAnalysis.colorWheel?.saturation;
- if (saturation > 70) {
- adapted.colorGrading = 'high-contrast';
- } else if (saturation < 30) {
- adapted.colorGrading = 'vintage';
- }
- }
- return adapted;
- }
- /**
- * 生成氛围感预览图URL
- */
- /**
- * 生成氛围感预览图URL(已弃用,使用 AtmospherePreviewService)
- * @deprecated 使用 AtmospherePreviewService.generateAtmospherePreview 替代
- */
- private generateAtmospherePreview(params: SceneParams, sceneType: SceneTemplate): string {
- // 这里应该调用实际的预览图生成服务
- // 目前返回模拟的URL
- const baseUrl = '/assets/previews/';
- const sceneId = sceneType.toString();
- const styleHash = this.generateStyleHash(params);
- return `${baseUrl}${sceneId}_${styleHash}.jpg`;
- }
- /**
- * 生成场景ID
- */
- private generateSceneId(sceneType: SceneTemplate): string {
- const timestamp = Date.now();
- return `${sceneType}_${timestamp}`;
- }
- /**
- * 计算映射置信度
- */
- private calculateConfidence(analysisResult: any, params: SceneParams): number {
- let confidence = 50; // 基础置信度
- // 根据分析结果的完整性调整置信度
- if (analysisResult.lightingAnalysis) confidence += 15;
- if (analysisResult.enhancedColorAnalysis) confidence += 15;
- if (analysisResult.textureAnalysis) confidence += 10;
- if (analysisResult.formAnalysis) confidence += 5;
- if (analysisResult.patternAnalysis) confidence += 5;
- return Math.min(confidence, 100);
- }
- /**
- * 生成优化建议
- */
- private generateSuggestions(analysisResult: any, params: SceneParams): string[] {
- const suggestions: string[] = [];
- // 基于灯光分析的建议
- if (analysisResult.lightingAnalysis?.ambientAnalysis?.lightingMood?.primary === 'dramatic') {
- suggestions.push('考虑增加重点照明以突出戏剧效果');
- }
- // 基于色彩分析的建议
- if (analysisResult.enhancedColorAnalysis?.colorWheel?.saturation < 30) {
- suggestions.push('可以适当增加色彩饱和度以提升视觉效果');
- }
- // 基于材质分析的建议
- if (analysisResult.textureAnalysis?.surfaceProperties?.roughness?.level === 'high') {
- suggestions.push('建议平衡粗糙和光滑材质的比例');
- }
- return suggestions;
- }
- /**
- * 生成风格哈希值
- */
- private generateStyleHash(params: SceneParams): string {
- const styleString = JSON.stringify({
- lighting: params.lighting.primaryLight.type,
- mood: params.lighting.ambientLight.mood,
- style: params.style.renderStyle,
- atmosphere: params.environment.atmosphere
- });
-
- // 简单的哈希函数
- let hash = 0;
- for (let i = 0; i < styleString.length; i++) {
- const char = styleString.charCodeAt(i);
- hash = ((hash << 5) - hash) + char;
- hash = hash & hash; // 转换为32位整数
- }
- return Math.abs(hash).toString(16).substring(0, 8);
- }
- /**
- * 获取默认场景参数
- */
- private getDefaultSceneParams(): SceneParams {
- return {
- lighting: {
- primaryLight: {
- type: 'natural',
- intensity: 70,
- temperature: 5500,
- direction: 'top'
- },
- ambientLight: {
- strength: 40,
- mood: 'calm'
- },
- shadows: {
- intensity: 50,
- softness: 60
- }
- },
- environment: {
- setting: 'indoor',
- atmosphere: 'modern',
- timeOfDay: 'afternoon',
- weatherCondition: 'sunny'
- },
- composition: {
- viewAngle: 'medium',
- perspective: 'eye-level',
- focusPoint: 'center',
- depth: 70
- },
- style: {
- renderStyle: 'photorealistic',
- colorGrading: 'natural',
- textureDetail: 'high'
- }
- };
- }
- /**
- * 初始化场景模板
- */
- private initializeSceneTemplates(): void {
- // 现代客厅
- this.sceneTemplates.set(SceneTemplate.LIVING_ROOM_MODERN, {
- lighting: {
- primaryLight: { type: 'natural', intensity: 75, temperature: 5500, direction: 'front' },
- ambientLight: { strength: 45, mood: 'calm' },
- shadows: { intensity: 40, softness: 70 }
- },
- environment: {
- setting: 'indoor',
- atmosphere: 'modern',
- timeOfDay: 'afternoon'
- },
- composition: {
- viewAngle: 'wide',
- perspective: 'eye-level',
- focusPoint: 'center',
- depth: 80
- },
- style: {
- renderStyle: 'photorealistic',
- colorGrading: 'modern',
- textureDetail: 'high'
- }
- });
- // 经典客厅
- this.sceneTemplates.set(SceneTemplate.LIVING_ROOM_CLASSIC, {
- lighting: {
- primaryLight: { type: 'artificial', intensity: 65, temperature: 3000, direction: 'top' },
- ambientLight: { strength: 55, mood: 'romantic' },
- shadows: { intensity: 60, softness: 50 }
- },
- environment: {
- setting: 'indoor',
- atmosphere: 'luxurious',
- timeOfDay: 'evening'
- },
- composition: {
- viewAngle: 'medium',
- perspective: 'eye-level',
- focusPoint: 'center',
- depth: 75
- },
- style: {
- renderStyle: 'artistic',
- colorGrading: 'warm',
- textureDetail: 'high'
- }
- });
- // 简约卧室
- this.sceneTemplates.set(SceneTemplate.BEDROOM_MINIMAL, {
- lighting: {
- primaryLight: { type: 'natural', intensity: 60, temperature: 5000, direction: 'left' },
- ambientLight: { strength: 30, mood: 'calm' },
- shadows: { intensity: 35, softness: 80 }
- },
- environment: {
- setting: 'indoor',
- atmosphere: 'minimal',
- timeOfDay: 'morning'
- },
- composition: {
- viewAngle: 'medium',
- perspective: 'eye-level',
- focusPoint: 'center',
- depth: 60
- },
- style: {
- renderStyle: 'minimalist',
- colorGrading: 'natural',
- textureDetail: 'medium'
- }
- });
- // 温馨卧室
- this.sceneTemplates.set(SceneTemplate.BEDROOM_COZY, {
- lighting: {
- primaryLight: { type: 'artificial', intensity: 50, temperature: 2700, direction: 'multiple' },
- ambientLight: { strength: 60, mood: 'romantic' },
- shadows: { intensity: 45, softness: 75 }
- },
- environment: {
- setting: 'indoor',
- atmosphere: 'cozy',
- timeOfDay: 'evening'
- },
- composition: {
- viewAngle: 'close-up',
- perspective: 'eye-level',
- focusPoint: 'center',
- depth: 50
- },
- style: {
- renderStyle: 'soft',
- colorGrading: 'warm',
- textureDetail: 'high'
- }
- });
- // 现代厨房
- this.sceneTemplates.set(SceneTemplate.KITCHEN_CONTEMPORARY, {
- lighting: {
- primaryLight: { type: 'artificial', intensity: 85, temperature: 4000, direction: 'top' },
- ambientLight: { strength: 40, mood: 'energetic' },
- shadows: { intensity: 50, softness: 60 }
- },
- environment: {
- setting: 'indoor',
- atmosphere: 'modern',
- timeOfDay: 'noon'
- },
- composition: {
- viewAngle: 'wide',
- perspective: 'eye-level',
- focusPoint: 'center',
- depth: 70
- },
- style: {
- renderStyle: 'photorealistic',
- colorGrading: 'high-contrast',
- textureDetail: 'high'
- }
- });
- // 添加更多模板...
- // 为了简洁,这里只展示几个主要模板的实现
- // 实际项目中应该为所有SceneTemplate枚举值提供对应的配置
- }
- }
|